mshtml: Wine Gecko 1.4 release.
[wine] / dlls / msxml3 / tests / domdoc.c
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-2011 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 "msxml2.h"
34 #include "msxml2did.h"
35 #include "ole2.h"
36 #include "dispex.h"
37
38 #include "initguid.h"
39 #include "objsafe.h"
40 #include "mshtml.h"
41
42 #include "wine/test.h"
43
44 DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
45 DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
46
47 #define DEFINE_EXPECT(func) \
48     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
49
50 #define SET_EXPECT(func) \
51     expect_ ## func = TRUE
52
53 #define CHECK_EXPECT2(func) \
54     do { \
55         ok(expect_ ##func, "unexpected call " #func "\n"); \
56         called_ ## func = TRUE; \
57     }while(0)
58
59 #define CHECK_CALLED(func) \
60     do { \
61         ok(called_ ## func, "expected " #func "\n"); \
62         expect_ ## func = called_ ## func = FALSE; \
63     }while(0)
64
65 static const char *debugstr_guid(REFIID riid)
66 {
67     static char buf[50];
68
69     if(!riid)
70         return "(null)";
71
72     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
73             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
74             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
75             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
76
77     return buf;
78 }
79
80 static int g_unexpectedcall, g_expectedcall;
81
82 typedef struct
83 {
84     IDispatch IDispatch_iface;
85     LONG ref;
86 } dispevent;
87
88 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
89 {
90     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
91 }
92
93 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
94 {
95     *ppvObject = NULL;
96
97     if ( IsEqualGUID( riid, &IID_IDispatch) ||
98          IsEqualGUID( riid, &IID_IUnknown) )
99     {
100         *ppvObject = iface;
101     }
102     else
103         return E_NOINTERFACE;
104
105     IDispatch_AddRef( iface );
106
107     return S_OK;
108 }
109
110 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
111 {
112     dispevent *This = impl_from_IDispatch( iface );
113     return InterlockedIncrement( &This->ref );
114 }
115
116 static ULONG WINAPI dispevent_Release(IDispatch *iface)
117 {
118     dispevent *This = impl_from_IDispatch( iface );
119     ULONG ref = InterlockedDecrement( &This->ref );
120
121     if (ref == 0)
122         HeapFree(GetProcessHeap(), 0, This);
123
124     return ref;
125 }
126
127 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
128 {
129     g_unexpectedcall++;
130     *pctinfo = 0;
131     return S_OK;
132 }
133
134 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
135         LCID lcid, ITypeInfo **ppTInfo)
136 {
137     g_unexpectedcall++;
138     return S_OK;
139 }
140
141 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
142         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
143 {
144     g_unexpectedcall++;
145     return S_OK;
146 }
147
148 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
149         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
150         EXCEPINFO *excepInfo, UINT *argErr)
151 {
152     ok(member == 0, "expected 0 member, got %d\n", member);
153     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
154     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
155
156     ok(params->cArgs == 0, "got %d\n", params->cArgs);
157     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
158     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
159     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
160
161     ok(result == NULL, "got %p\n", result);
162     ok(excepInfo == NULL, "got %p\n", excepInfo);
163     ok(argErr == NULL, "got %p\n", argErr);
164
165     g_expectedcall++;
166     return E_FAIL;
167 }
168
169 static const IDispatchVtbl dispeventVtbl =
170 {
171     dispevent_QueryInterface,
172     dispevent_AddRef,
173     dispevent_Release,
174     dispevent_GetTypeInfoCount,
175     dispevent_GetTypeInfo,
176     dispevent_GetIDsOfNames,
177     dispevent_Invoke
178 };
179
180 static IDispatch* create_dispevent(void)
181 {
182     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
183
184     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
185     event->ref = 1;
186
187     return (IDispatch*)&event->IDispatch_iface;
188 }
189
190 /* object site */
191 DEFINE_EXPECT(site_qi_IServiceProvider);
192 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
193 DEFINE_EXPECT(site_qi_IOleClientSite);
194
195 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
196 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
197 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
198 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
199 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
200
201 DEFINE_EXPECT(htmldoc2_get_all);
202 DEFINE_EXPECT(htmldoc2_get_url);
203 DEFINE_EXPECT(collection_get_length);
204
205 typedef struct
206 {
207     IServiceProvider IServiceProvider_iface;
208 } testprov_t;
209
210 testprov_t testprov;
211
212 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
213 {
214     *ppvObject = NULL;
215
216     if (IsEqualGUID(riid, &IID_IServiceProvider))
217         CHECK_EXPECT2(site_qi_IServiceProvider);
218
219     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
220         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
221
222     if (IsEqualGUID(riid, &IID_IOleClientSite))
223         CHECK_EXPECT2(site_qi_IOleClientSite);
224
225     if (IsEqualGUID(riid, &IID_IUnknown))
226          *ppvObject = iface;
227     else if (IsEqualGUID(riid, &IID_IServiceProvider))
228          *ppvObject = &testprov.IServiceProvider_iface;
229
230     if (*ppvObject) IUnknown_AddRef(iface);
231
232     return *ppvObject ? S_OK : E_NOINTERFACE;
233 }
234
235 static ULONG WINAPI site_AddRef(IUnknown *iface)
236 {
237     return 2;
238 }
239
240 static ULONG WINAPI site_Release(IUnknown *iface)
241 {
242     return 1;
243 }
244
245 static const IUnknownVtbl testsiteVtbl =
246 {
247     site_QueryInterface,
248     site_AddRef,
249     site_Release
250 };
251
252 typedef struct
253 {
254     IUnknown IUnknown_iface;
255 } testsite_t;
256
257 static testsite_t testsite = { { &testsiteVtbl } };
258
259 /* test IHTMLElementCollection */
260 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
261 {
262     ok(0, "unexpected call\n");
263     *ppvObject = NULL;
264     return E_NOINTERFACE;
265 }
266
267 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
268 {
269     return 2;
270 }
271
272 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
273 {
274     return 1;
275 }
276
277 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
278 {
279     ok(0, "unexpected call\n");
280     return E_NOTIMPL;
281 }
282
283 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
284                                                 LCID lcid, ITypeInfo **ppTInfo)
285 {
286     ok(0, "unexpected call\n");
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
291                                                 LPOLESTR *rgszNames, UINT cNames,
292                                                 LCID lcid, DISPID *rgDispId)
293 {
294     ok(0, "unexpected call\n");
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
299                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
300                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
301 {
302     ok(0, "unexpected call\n");
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
307 {
308     ok(0, "unexpected call\n");
309     return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
313 {
314     ok(0, "unexpected call\n");
315     return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
319 {
320     CHECK_EXPECT2(collection_get_length);
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
325 {
326     ok(0, "unexpected call\n");
327     return E_NOTIMPL;
328 }
329
330 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
331 {
332     ok(0, "unexpected call\n");
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
337 {
338     ok(0, "unexpected call\n");
339     return E_NOTIMPL;
340 }
341
342 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
343     htmlecoll_QueryInterface,
344     htmlecoll_AddRef,
345     htmlecoll_Release,
346     htmlecoll_GetTypeInfoCount,
347     htmlecoll_GetTypeInfo,
348     htmlecoll_GetIDsOfNames,
349     htmlecoll_Invoke,
350
351     htmlecoll_toString,
352     htmlecoll_put_length,
353     htmlecoll_get_length,
354     htmlecoll_get__newEnum,
355     htmlecoll_item,
356     htmlecoll_tags
357 };
358
359 typedef struct
360 {
361     IHTMLElementCollection IHTMLElementCollection_iface;
362 } testhtmlecoll_t;
363
364 static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
365
366 /* test IHTMLDocument2 */
367 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
368 {
369    trace("\n");
370    *ppvObject = NULL;
371    return E_NOINTERFACE;
372 }
373
374 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
375 {
376     return 2;
377 }
378
379 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
380 {
381     return 1;
382 }
383
384 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
385 {
386     ok(0, "unexpected call\n");
387     return E_NOTIMPL;
388 }
389
390 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
391                                                 LCID lcid, ITypeInfo **ppTInfo)
392 {
393     ok(0, "unexpected call\n");
394     return E_NOTIMPL;
395 }
396
397 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
398                                                 LPOLESTR *rgszNames, UINT cNames,
399                                                 LCID lcid, DISPID *rgDispId)
400 {
401     ok(0, "unexpected call\n");
402     return E_NOTIMPL;
403 }
404
405 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
406                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
407                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
408 {
409     ok(0, "unexpected call\n");
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
414 {
415     ok(0, "unexpected call\n");
416     return E_NOTIMPL;
417 }
418
419 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
420 {
421     CHECK_EXPECT2(htmldoc2_get_all);
422     *p = &htmlecoll.IHTMLElementCollection_iface;
423     return S_OK;
424 }
425
426 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
427 {
428     ok(0, "unexpected call\n");
429     return E_NOTIMPL;
430 }
431
432 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
433 {
434     ok(0, "unexpected call\n");
435     return E_NOTIMPL;
436 }
437
438 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
439 {
440     ok(0, "unexpected call\n");
441     return E_NOTIMPL;
442 }
443
444 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
445 {
446     ok(0, "unexpected call\n");
447     return E_NOTIMPL;
448 }
449
450 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
451 {
452     ok(0, "unexpected call\n");
453     return E_NOTIMPL;
454 }
455
456 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
457 {
458     ok(0, "unexpected call\n");
459     return E_NOTIMPL;
460 }
461
462 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
463 {
464     ok(0, "unexpected call\n");
465     return E_NOTIMPL;
466 }
467
468 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
469 {
470     ok(0, "unexpected call\n");
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
475 {
476     ok(0, "unexpected call\n");
477     return E_NOTIMPL;
478 }
479
480 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
481 {
482     ok(0, "unexpected call\n");
483     return E_NOTIMPL;
484 }
485
486 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
487 {
488     ok(0, "unexpected call\n");
489     return E_NOTIMPL;
490 }
491
492 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
493 {
494     ok(0, "unexpected call\n");
495     return E_NOTIMPL;
496 }
497
498 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
499 {
500     ok(0, "unexpected call\n");
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
505 {
506     ok(0, "unexpected call\n");
507     return E_NOTIMPL;
508 }
509
510 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
511 {
512     ok(0, "unexpected call\n");
513     return E_NOTIMPL;
514 }
515
516 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
517 {
518     ok(0, "unexpected call\n");
519     return E_NOTIMPL;
520 }
521
522 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
523 {
524     ok(0, "unexpected call\n");
525     return E_NOTIMPL;
526 }
527
528 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
529 {
530     ok(0, "unexpected call\n");
531     return E_NOTIMPL;
532 }
533
534 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
535 {
536     ok(0, "unexpected call\n");
537     return E_NOTIMPL;
538 }
539
540 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
541 {
542     ok(0, "unexpected call\n");
543     return E_NOTIMPL;
544 }
545
546 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
547 {
548     ok(0, "unexpected call\n");
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
553 {
554     ok(0, "unexpected call\n");
555     return E_NOTIMPL;
556 }
557
558 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
559 {
560     ok(0, "unexpected call\n");
561     return E_NOTIMPL;
562 }
563
564 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
565 {
566     ok(0, "unexpected call\n");
567     return E_NOTIMPL;
568 }
569
570 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
571 {
572     ok(0, "unexpected call\n");
573     return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
577 {
578     ok(0, "unexpected call\n");
579     return E_NOTIMPL;
580 }
581
582 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
583 {
584     ok(0, "unexpected call\n");
585     return E_NOTIMPL;
586 }
587
588 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
589 {
590     ok(0, "unexpected call\n");
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
595 {
596     ok(0, "unexpected call\n");
597     return E_NOTIMPL;
598 }
599
600 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
601 {
602     ok(0, "unexpected call\n");
603     return E_NOTIMPL;
604 }
605
606 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
607 {
608     ok(0, "unexpected call\n");
609     return E_NOTIMPL;
610 }
611
612 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
613 {
614     CHECK_EXPECT2(htmldoc2_get_url);
615     *p = SysAllocString(NULL);
616     return S_OK;
617 }
618
619 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
620 {
621     ok(0, "unexpected call\n");
622     return E_NOTIMPL;
623 }
624
625 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
626 {
627     ok(0, "unexpected call\n");
628     return E_NOTIMPL;
629 }
630
631 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
632 {
633     ok(0, "unexpected call\n");
634     return E_NOTIMPL;
635 }
636
637 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
638 {
639     ok(0, "unexpected call\n");
640     return E_NOTIMPL;
641 }
642
643 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
644 {
645     ok(0, "unexpected call\n");
646     return E_NOTIMPL;
647 }
648
649 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
650 {
651     ok(0, "unexpected call\n");
652     return E_NOTIMPL;
653 }
654
655 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
656 {
657     ok(0, "unexpected call\n");
658     return E_NOTIMPL;
659 }
660
661 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
662 {
663     ok(0, "unexpected call\n");
664     return E_NOTIMPL;
665 }
666
667 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
668 {
669     ok(0, "unexpected call\n");
670     return E_NOTIMPL;
671 }
672
673 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
674 {
675     ok(0, "unexpected call\n");
676     return E_NOTIMPL;
677 }
678
679 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
680 {
681     ok(0, "unexpected call\n");
682     return E_NOTIMPL;
683 }
684
685 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
686 {
687     ok(0, "unexpected call\n");
688     return E_NOTIMPL;
689 }
690
691 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
692 {
693     ok(0, "unexpected call\n");
694     return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
698 {
699     ok(0, "unexpected call\n");
700     return E_NOTIMPL;
701 }
702
703 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
704 {
705     ok(0, "unexpected call\n");
706     return E_NOTIMPL;
707 }
708
709 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
710 {
711     ok(0, "unexpected call\n");
712     return E_NOTIMPL;
713 }
714
715 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
716 {
717     ok(0, "unexpected call\n");
718     return E_NOTIMPL;
719 }
720
721 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
722 {
723     ok(0, "unexpected call\n");
724     return E_NOTIMPL;
725 }
726
727 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
728 {
729     ok(0, "unexpected call\n");
730     return E_NOTIMPL;
731 }
732
733 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
734 {
735     ok(0, "unexpected call\n");
736     return E_NOTIMPL;
737 }
738
739 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
740                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
741 {
742     ok(0, "unexpected call\n");
743     return E_NOTIMPL;
744 }
745
746 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
747 {
748     ok(0, "unexpected call\n");
749     return E_NOTIMPL;
750 }
751
752 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
753 {
754     ok(0, "unexpected call\n");
755     return E_NOTIMPL;
756 }
757
758 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
759                                                         VARIANT_BOOL *pfRet)
760 {
761     ok(0, "unexpected call\n");
762     return E_NOTIMPL;
763 }
764
765 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
766                                                         VARIANT_BOOL *pfRet)
767 {
768     ok(0, "unexpected call\n");
769     return E_NOTIMPL;
770 }
771
772 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
773                                                         VARIANT_BOOL *pfRet)
774 {
775     ok(0, "unexpected call\n");
776     return E_NOTIMPL;
777 }
778
779 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
780                                                         VARIANT_BOOL *pfRet)
781 {
782     ok(0, "unexpected call\n");
783     return E_NOTIMPL;
784 }
785
786 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
787                                                         BSTR *pfRet)
788 {
789     ok(0, "unexpected call\n");
790     return E_NOTIMPL;
791 }
792
793 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
794                                                         VARIANT *pfRet)
795 {
796     ok(0, "unexpected call\n");
797     return E_NOTIMPL;
798 }
799
800 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
801                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
802 {
803     ok(0, "unexpected call\n");
804     return E_NOTIMPL;
805 }
806
807 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
808                                                         VARIANT_BOOL *pfRet)
809 {
810     ok(0, "unexpected call\n");
811     return E_NOTIMPL;
812 }
813
814 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
815                                                  IHTMLElement **newElem)
816 {
817     ok(0, "unexpected call\n");
818     return E_NOTIMPL;
819 }
820
821 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
822 {
823     ok(0, "unexpected call\n");
824     return E_NOTIMPL;
825 }
826
827 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
828 {
829     ok(0, "unexpected call\n");
830     return E_NOTIMPL;
831 }
832
833 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
834 {
835     ok(0, "unexpected call\n");
836     return E_NOTIMPL;
837 }
838
839 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
840 {
841     ok(0, "unexpected call\n");
842     return E_NOTIMPL;
843 }
844
845 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
846 {
847     ok(0, "unexpected call\n");
848     return E_NOTIMPL;
849 }
850
851 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
852 {
853     ok(0, "unexpected call\n");
854     return E_NOTIMPL;
855 }
856
857 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
858 {
859     ok(0, "unexpected call\n");
860     return E_NOTIMPL;
861 }
862
863 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
864 {
865     ok(0, "unexpected call\n");
866     return E_NOTIMPL;
867 }
868
869 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
870 {
871     ok(0, "unexpected call\n");
872     return E_NOTIMPL;
873 }
874
875 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
876 {
877     ok(0, "unexpected call\n");
878     return E_NOTIMPL;
879 }
880
881 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
882 {
883     ok(0, "unexpected call\n");
884     return E_NOTIMPL;
885 }
886
887 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
888 {
889     ok(0, "unexpected call\n");
890     return E_NOTIMPL;
891 }
892
893 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
894 {
895     ok(0, "unexpected call\n");
896     return E_NOTIMPL;
897 }
898
899 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
900 {
901     ok(0, "unexpected call\n");
902     return E_NOTIMPL;
903 }
904
905 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
906 {
907     ok(0, "unexpected call\n");
908     return E_NOTIMPL;
909 }
910
911 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
912 {
913     ok(0, "unexpected call\n");
914     return E_NOTIMPL;
915 }
916
917 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
918 {
919     ok(0, "unexpected call\n");
920     return E_NOTIMPL;
921 }
922
923 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
924 {
925     ok(0, "unexpected call\n");
926     return E_NOTIMPL;
927 }
928
929 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
930 {
931     ok(0, "unexpected call\n");
932     return E_NOTIMPL;
933 }
934
935 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
936 {
937     ok(0, "unexpected call\n");
938     return E_NOTIMPL;
939 }
940
941 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
942 {
943     ok(0, "unexpected call\n");
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
948 {
949     ok(0, "unexpected call\n");
950     return E_NOTIMPL;
951 }
952
953 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
954 {
955     ok(0, "unexpected call\n");
956     return E_NOTIMPL;
957 }
958
959 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
960 {
961     ok(0, "unexpected call\n");
962     return E_NOTIMPL;
963 }
964
965 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
966 {
967     ok(0, "unexpected call\n");
968     return E_NOTIMPL;
969 }
970
971 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
972 {
973     ok(0, "unexpected call\n");
974     return E_NOTIMPL;
975 }
976
977 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
978 {
979     ok(0, "unexpected call\n");
980     return E_NOTIMPL;
981 }
982
983 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
984 {
985     ok(0, "unexpected call\n");
986     return E_NOTIMPL;
987 }
988
989 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
990 {
991     ok(0, "unexpected call\n");
992     return E_NOTIMPL;
993 }
994
995 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
996 {
997     ok(0, "unexpected call\n");
998     return E_NOTIMPL;
999 }
1000
1001 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1002 {
1003     ok(0, "unexpected call\n");
1004     return E_NOTIMPL;
1005 }
1006
1007 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1008 {
1009     ok(0, "unexpected call\n");
1010     return E_NOTIMPL;
1011 }
1012
1013 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1014 {
1015     ok(0, "unexpected call\n");
1016     return E_NOTIMPL;
1017 }
1018
1019 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1020 {
1021     ok(0, "unexpected call\n");
1022     return E_NOTIMPL;
1023 }
1024
1025 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1026                                                         IHTMLElement **elementHit)
1027 {
1028     ok(0, "unexpected call\n");
1029     return E_NOTIMPL;
1030 }
1031
1032 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1033 {
1034     ok(0, "unexpected call\n");
1035     return E_NOTIMPL;
1036 }
1037
1038 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
1039                                                    IHTMLStyleSheetsCollection **p)
1040 {
1041     ok(0, "unexpected call\n");
1042     return E_NOTIMPL;
1043 }
1044
1045 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1046 {
1047     ok(0, "unexpected call\n");
1048     return E_NOTIMPL;
1049 }
1050
1051 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1052 {
1053     ok(0, "unexpected call\n");
1054     return E_NOTIMPL;
1055 }
1056
1057 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1058 {
1059     ok(0, "unexpected call\n");
1060     return E_NOTIMPL;
1061 }
1062
1063 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1064 {
1065     ok(0, "unexpected call\n");
1066     return E_NOTIMPL;
1067 }
1068
1069 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
1070 {
1071     ok(0, "unexpected call\n");
1072     return E_NOTIMPL;
1073 }
1074
1075 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1076                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1077 {
1078     ok(0, "unexpected call\n");
1079     return E_NOTIMPL;
1080 }
1081
1082 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
1083     htmldoc2_QueryInterface,
1084     htmldoc2_AddRef,
1085     htmldoc2_Release,
1086     htmldoc2_GetTypeInfoCount,
1087     htmldoc2_GetTypeInfo,
1088     htmldoc2_GetIDsOfNames,
1089     htmldoc2_Invoke,
1090     htmldoc2_get_Script,
1091     htmldoc2_get_all,
1092     htmldoc2_get_body,
1093     htmldoc2_get_activeElement,
1094     htmldoc2_get_images,
1095     htmldoc2_get_applets,
1096     htmldoc2_get_links,
1097     htmldoc2_get_forms,
1098     htmldoc2_get_anchors,
1099     htmldoc2_put_title,
1100     htmldoc2_get_title,
1101     htmldoc2_get_scripts,
1102     htmldoc2_put_designMode,
1103     htmldoc2_get_designMode,
1104     htmldoc2_get_selection,
1105     htmldoc2_get_readyState,
1106     htmldoc2_get_frames,
1107     htmldoc2_get_embeds,
1108     htmldoc2_get_plugins,
1109     htmldoc2_put_alinkColor,
1110     htmldoc2_get_alinkColor,
1111     htmldoc2_put_bgColor,
1112     htmldoc2_get_bgColor,
1113     htmldoc2_put_fgColor,
1114     htmldoc2_get_fgColor,
1115     htmldoc2_put_linkColor,
1116     htmldoc2_get_linkColor,
1117     htmldoc2_put_vlinkColor,
1118     htmldoc2_get_vlinkColor,
1119     htmldoc2_get_referrer,
1120     htmldoc2_get_location,
1121     htmldoc2_get_lastModified,
1122     htmldoc2_put_URL,
1123     htmldoc2_get_URL,
1124     htmldoc2_put_domain,
1125     htmldoc2_get_domain,
1126     htmldoc2_put_cookie,
1127     htmldoc2_get_cookie,
1128     htmldoc2_put_expando,
1129     htmldoc2_get_expando,
1130     htmldoc2_put_charset,
1131     htmldoc2_get_charset,
1132     htmldoc2_put_defaultCharset,
1133     htmldoc2_get_defaultCharset,
1134     htmldoc2_get_mimeType,
1135     htmldoc2_get_fileSize,
1136     htmldoc2_get_fileCreatedDate,
1137     htmldoc2_get_fileModifiedDate,
1138     htmldoc2_get_fileUpdatedDate,
1139     htmldoc2_get_security,
1140     htmldoc2_get_protocol,
1141     htmldoc2_get_nameProp,
1142     htmldoc2_write,
1143     htmldoc2_writeln,
1144     htmldoc2_open,
1145     htmldoc2_close,
1146     htmldoc2_clear,
1147     htmldoc2_queryCommandSupported,
1148     htmldoc2_queryCommandEnabled,
1149     htmldoc2_queryCommandState,
1150     htmldoc2_queryCommandIndeterm,
1151     htmldoc2_queryCommandText,
1152     htmldoc2_queryCommandValue,
1153     htmldoc2_execCommand,
1154     htmldoc2_execCommandShowHelp,
1155     htmldoc2_createElement,
1156     htmldoc2_put_onhelp,
1157     htmldoc2_get_onhelp,
1158     htmldoc2_put_onclick,
1159     htmldoc2_get_onclick,
1160     htmldoc2_put_ondblclick,
1161     htmldoc2_get_ondblclick,
1162     htmldoc2_put_onkeyup,
1163     htmldoc2_get_onkeyup,
1164     htmldoc2_put_onkeydown,
1165     htmldoc2_get_onkeydown,
1166     htmldoc2_put_onkeypress,
1167     htmldoc2_get_onkeypress,
1168     htmldoc2_put_onmouseup,
1169     htmldoc2_get_onmouseup,
1170     htmldoc2_put_onmousedown,
1171     htmldoc2_get_onmousedown,
1172     htmldoc2_put_onmousemove,
1173     htmldoc2_get_onmousemove,
1174     htmldoc2_put_onmouseout,
1175     htmldoc2_get_onmouseout,
1176     htmldoc2_put_onmouseover,
1177     htmldoc2_get_onmouseover,
1178     htmldoc2_put_onreadystatechange,
1179     htmldoc2_get_onreadystatechange,
1180     htmldoc2_put_onafterupdate,
1181     htmldoc2_get_onafterupdate,
1182     htmldoc2_put_onrowexit,
1183     htmldoc2_get_onrowexit,
1184     htmldoc2_put_onrowenter,
1185     htmldoc2_get_onrowenter,
1186     htmldoc2_put_ondragstart,
1187     htmldoc2_get_ondragstart,
1188     htmldoc2_put_onselectstart,
1189     htmldoc2_get_onselectstart,
1190     htmldoc2_elementFromPoint,
1191     htmldoc2_get_parentWindow,
1192     htmldoc2_get_styleSheets,
1193     htmldoc2_put_onbeforeupdate,
1194     htmldoc2_get_onbeforeupdate,
1195     htmldoc2_put_onerrorupdate,
1196     htmldoc2_get_onerrorupdate,
1197     htmldoc2_toString,
1198     htmldoc2_createStyleSheet
1199 };
1200
1201 typedef struct
1202 {
1203     IHTMLDocument2 IHTMLDocument2_iface;
1204 } testhtmldoc2_t;
1205
1206 static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
1207
1208 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1209 {
1210     *ppvObject = NULL;
1211
1212     if (IsEqualGUID(riid, &IID_IUnknown) ||
1213         IsEqualGUID(riid, &IID_IServiceProvider))
1214     {
1215         *ppvObject = iface;
1216         IServiceProvider_AddRef(iface);
1217         return S_OK;
1218     }
1219
1220     ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
1221
1222     return E_NOINTERFACE;
1223 }
1224
1225 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1226 {
1227     return 2;
1228 }
1229
1230 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1231 {
1232     return 1;
1233 }
1234
1235 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1236 {
1237     *obj = NULL;
1238
1239     if (IsEqualGUID(service, &SID_SBindHost) &&
1240         IsEqualGUID(riid, &IID_IBindHost))
1241     {
1242         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1243     }
1244     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1245              IsEqualGUID(riid, &IID_IHTMLDocument2))
1246     {
1247         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1248     }
1249     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1250              IsEqualGUID(riid, &IID_IHTMLDocument2))
1251     {
1252         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1253         *obj = &htmldoc2.IHTMLDocument2_iface;
1254         return S_OK;
1255     }
1256     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1257              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1258     {
1259         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1260     }
1261     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1262              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1263     {
1264         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1265     }
1266     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1267              IsEqualGUID(riid, &IID_IStream))
1268     {
1269         /* FIXME: unidentified service id */
1270     }
1271     else
1272         ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
1273
1274     return E_NOTIMPL;
1275 }
1276
1277 static const IServiceProviderVtbl testprovVtbl =
1278 {
1279     sp_QueryInterface,
1280     sp_AddRef,
1281     sp_Release,
1282     sp_QueryService
1283 };
1284
1285 testprov_t testprov = { { &testprovVtbl } };
1286
1287 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1288 static void _expect_children(IXMLDOMNode *node, int line)
1289 {
1290     VARIANT_BOOL b;
1291     HRESULT hr;
1292
1293     b = VARIANT_FALSE;
1294     hr = IXMLDOMNode_hasChildNodes(node, &b);
1295     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1296     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1297 }
1298
1299 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1300 static void _expect_no_children(IXMLDOMNode *node, int line)
1301 {
1302     VARIANT_BOOL b;
1303     HRESULT hr;
1304
1305     b = VARIANT_TRUE;
1306     hr = IXMLDOMNode_hasChildNodes(node, &b);
1307     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1308     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1309 }
1310
1311 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1312 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1313 {
1314     ULONG rc = IUnknown_AddRef(obj);
1315     IUnknown_Release(obj);
1316     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1317 }
1318
1319 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1320 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1321 {
1322     LONG length;
1323     HRESULT hr;
1324
1325     length = 0;
1326     hr = IXMLDOMNodeList_get_length(list, &length);
1327     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1328     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1329 }
1330
1331 #define EXPECT_HR(hr,hr_exp) \
1332     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1333
1334 static const WCHAR szEmpty[] = { 0 };
1335 static const WCHAR szIncomplete[] = {
1336     '<','?','x','m','l',' ',
1337     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1338 };
1339 static const WCHAR szComplete1[] = {
1340     '<','?','x','m','l',' ',
1341     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1342     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1343 };
1344 static const WCHAR szComplete2[] = {
1345     '<','?','x','m','l',' ',
1346     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1347     '<','o','>','<','/','o','>','\n',0
1348 };
1349 static const WCHAR szComplete3[] = {
1350     '<','?','x','m','l',' ',
1351     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1352     '<','a','>','<','/','a','>','\n',0
1353 };
1354 static const WCHAR szComplete4[] = {
1355     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1356     '<','l','c',' ','d','l','=','\'','s','t','r','1','\'','>','\n',
1357         '<','b','s',' ','v','r','=','\'','s','t','r','2','\'',' ','s','z','=','\'','1','2','3','4','\'','>',
1358             'f','n','1','.','t','x','t','\n',
1359         '<','/','b','s','>','\n',
1360         '<','p','r',' ','i','d','=','\'','s','t','r','3','\'',' ','v','r','=','\'','1','.','2','.','3','\'',' ',
1361                     'p','n','=','\'','w','i','n','e',' ','2','0','0','5','0','8','0','4','\'','>','\n',
1362             'f','n','2','.','t','x','t','\n',
1363         '<','/','p','r','>','\n',
1364         '<','e','m','p','t','y','>','<','/','e','m','p','t','y','>','\n',
1365         '<','f','o','>','\n',
1366             '<','b','a','>','\n',
1367                 'f','1','\n',
1368             '<','/','b','a','>','\n',
1369         '<','/','f','o','>','\n',
1370     '<','/','l','c','>','\n',0
1371 };
1372 static const WCHAR szComplete5[] = {
1373     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1374     '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','"',
1375     ' ','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','"','>',
1376         '<','S',':','s','c','o','p','e','>',
1377             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1378         '<','/','S',':','s','c','o','p','e','>',
1379         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1380             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1381             'c','o','m','p','u','t','e','r',
1382         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1383     '<','/','S',':','s','e','a','r','c','h','>',0
1384 };
1385
1386 static const WCHAR szComplete6[] = {
1387     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1388     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1389     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1390 };
1391
1392 static const CHAR szNonUnicodeXML[] =
1393 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1394 "<open></open>\n";
1395
1396 static const CHAR szExampleXML[] =
1397 "<?xml version='1.0' encoding='utf-8'?>\n"
1398 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1399 "    <elem>\n"
1400 "        <a>A1 field</a>\n"
1401 "        <b>B1 field</b>\n"
1402 "        <c>C1 field</c>\n"
1403 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1404 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1405 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1406 "            </html>\n"
1407 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1408 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1409 "            </html>\n"
1410 "        </description>\n"
1411 "    </elem>\n"
1412 "\n"
1413 "    <elem>\n"
1414 "        <a>A2 field</a>\n"
1415 "        <b>B2 field</b>\n"
1416 "        <c type=\"old\">C2 field</c>\n"
1417 "    </elem>\n"
1418 "\n"
1419 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1420 "        <a>A3 field</a>\n"
1421 "        <b>B3 field</b>\n"
1422 "        <c>C3 field</c>\n"
1423 "    </elem>\n"
1424 "\n"
1425 "    <elem>\n"
1426 "        <a>A4 field</a>\n"
1427 "        <b>B4 field</b>\n"
1428 "        <foo:c>C4 field</foo:c>\n"
1429 "    </elem>\n"
1430 "</root>\n";
1431
1432 static const CHAR szNodeTypesXML[] =
1433 "<?xml version='1.0'?>"
1434 "<!-- comment node 0 -->"
1435 "<root id='0' depth='0'>"
1436 "   <!-- comment node 1 -->"
1437 "   text node 0"
1438 "   <x id='1' depth='1'>"
1439 "       <?foo value='PI for x'?>"
1440 "       <!-- comment node 2 -->"
1441 "       text node 1"
1442 "       <a id='3' depth='2'/>"
1443 "       <b id='4' depth='2'/>"
1444 "       <c id='5' depth='2'/>"
1445 "   </x>"
1446 "   <y id='2' depth='1'>"
1447 "       <?bar value='PI for y'?>"
1448 "       <!-- comment node 3 -->"
1449 "       text node 2"
1450 "       <a id='6' depth='2'/>"
1451 "       <b id='7' depth='2'/>"
1452 "       <c id='8' depth='2'/>"
1453 "   </y>"
1454 "</root>";
1455
1456 static const CHAR szTransformXML[] =
1457 "<?xml version=\"1.0\"?>\n"
1458 "<greeting>\n"
1459 "Hello World\n"
1460 "</greeting>";
1461
1462 static  const CHAR szTransformSSXML[] =
1463 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1464 "   <xsl:output method=\"html\"/>\n"
1465 "   <xsl:template match=\"/\">\n"
1466 "       <xsl:apply-templates select=\"greeting\"/>\n"
1467 "   </xsl:template>\n"
1468 "   <xsl:template match=\"greeting\">\n"
1469 "       <html>\n"
1470 "           <body>\n"
1471 "               <h1>\n"
1472 "                   <xsl:value-of select=\".\"/>\n"
1473 "               </h1>\n"
1474 "           </body>\n"
1475 "       </html>\n"
1476 "   </xsl:template>\n"
1477 "</xsl:stylesheet>";
1478
1479 static  const CHAR szTransformOutput[] =
1480 "<html><body><h1>"
1481 "Hello World"
1482 "</h1></body></html>";
1483
1484 static const CHAR szTypeValueXML[] =
1485 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1486 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1487 "   <string>Wine</string>\n"
1488 "   <string2 dt:dt=\"string\">String</string2>\n"
1489 "   <number dt:dt=\"number\">12.44</number>\n"
1490 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1491 "   <int dt:dt=\"int\">-13</int>\n"
1492 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1493 "   <bool dt:dt=\"boolean\">1</bool>\n"
1494 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1495 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1496 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1497 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1498 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1499 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1500 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1501 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1502 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1503 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1504 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1505 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1506 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1507 "   <float dt:dt=\"float\">41221.421</float>\n"
1508 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1509 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1510 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1511 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1512 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1513 "</root>";
1514
1515 static const CHAR szBasicTransformSSXMLPart1[] =
1516 "<?xml version=\"1.0\"?>"
1517 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1518 "<xsl:output method=\"html\"/>\n"
1519 "<xsl:template match=\"/\">"
1520 "<HTML><BODY><TABLE>"
1521 "        <xsl:apply-templates select='document(\"";
1522
1523 static const CHAR szBasicTransformSSXMLPart2[] =
1524 "\")/bottle/wine'>"
1525 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1526 "        </xsl:apply-templates>"
1527 "</TABLE></BODY></HTML>"
1528 "</xsl:template>"
1529 "<xsl:template match=\"bottle\">"
1530 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1531 "</xsl:template>"
1532 "<xsl:template match=\"name\">"
1533 "   <TD><xsl:apply-templates /></TD>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"cost\">"
1536 "   <TD><xsl:apply-templates /></TD>"
1537 "</xsl:template>"
1538 "</xsl:stylesheet>";
1539
1540 static const CHAR szBasicTransformXML[] =
1541 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1542
1543 static const CHAR szBasicTransformOutput[] =
1544 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1545
1546 #define SZ_EMAIL_DTD \
1547 "<!DOCTYPE email ["\
1548 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1549 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1550 "       <!ATTLIST email sent (yes|no) \"no\">"\
1551 "   <!ELEMENT recipients    (to+,cc*)>"\
1552 "   <!ELEMENT to            (#PCDATA)>"\
1553 "       <!ATTLIST to name CDATA #IMPLIED>"\
1554 "   <!ELEMENT cc            (#PCDATA)>"\
1555 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1556 "   <!ELEMENT from          (#PCDATA)>"\
1557 "       <!ATTLIST from name CDATA #IMPLIED>"\
1558 "   <!ELEMENT reply-to      (#PCDATA)>"\
1559 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1560 "   <!ELEMENT subject       ANY>"\
1561 "   <!ELEMENT body          ANY>"\
1562 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1563 "   <!ELEMENT attachment    (#PCDATA)>"\
1564 "       <!ATTLIST attachment id ID #REQUIRED>"\
1565 "]>"
1566
1567 static const CHAR szEmailXML[] =
1568 "<?xml version=\"1.0\"?>"
1569 SZ_EMAIL_DTD
1570 "<email attachments=\"patch1\">"
1571 "   <recipients>"
1572 "       <to>wine-patches@winehq.org</to>"
1573 "   </recipients>"
1574 "   <from name=\"Anonymous\">user@localhost</from>"
1575 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1576 "   <body>"
1577 "       It no longer causes spontaneous combustion..."
1578 "   </body>"
1579 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1580 "</email>";
1581
1582 static const CHAR szEmailXML_0D[] =
1583 "<?xml version=\"1.0\"?>"
1584 SZ_EMAIL_DTD
1585 "<email attachments=\"patch1\">"
1586 "   <recipients>"
1587 "       <to>wine-patches@winehq.org</to>"
1588 "   </recipients>"
1589 "   <from name=\"Anonymous\">user@localhost</from>"
1590 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1591 "   <body>"
1592 "       <undecl />"
1593 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1594 "   </body>"
1595 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1596 "</email>";
1597
1598 static const CHAR szEmailXML_0E[] =
1599 "<?xml version=\"1.0\"?>"
1600 SZ_EMAIL_DTD
1601 "<email attachments=\"patch1\">"
1602 "   <recipients>"
1603 "       <to>wine-patches@winehq.org</to>"
1604 "   </recipients>"
1605 "   <from name=\"Anonymous\">user@localhost</from>"
1606 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1607 "   <body>"
1608 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1609 "   </body>"
1610 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1611 "</email>";
1612
1613 static const CHAR szEmailXML_11[] =
1614 "<?xml version=\"1.0\"?>"
1615 SZ_EMAIL_DTD
1616 "<email attachments=\"patch1\">"
1617 "   <recipients>"
1618 "   </recipients>"
1619 "   <from name=\"Anonymous\">user@localhost</from>"
1620 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1621 "   <body>"
1622 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1623 "   </body>"
1624 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1625 "</email>";
1626
1627 static const CHAR szEmailXML_13[] =
1628 "<?xml version=\"1.0\"?>"
1629 SZ_EMAIL_DTD
1630 "<msg attachments=\"patch1\">"
1631 "   <recipients>"
1632 "       <to>wine-patches@winehq.org</to>"
1633 "   </recipients>"
1634 "   <from name=\"Anonymous\">user@localhost</from>"
1635 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1636 "   <body>"
1637 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1638 "   </body>"
1639 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1640 "</msg>";
1641
1642 static const CHAR szEmailXML_14[] =
1643 "<?xml version=\"1.0\"?>"
1644 SZ_EMAIL_DTD
1645 "<email attachments=\"patch1\">"
1646 "   <to>wine-patches@winehq.org</to>"
1647 "   <from name=\"Anonymous\">user@localhost</from>"
1648 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1649 "   <body>"
1650 "       XML_INVALID_CONTENT 0xC00CE014"
1651 "   </body>"
1652 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1653 "</email>";
1654
1655 static const CHAR szEmailXML_15[] =
1656 "<?xml version=\"1.0\"?>"
1657 SZ_EMAIL_DTD
1658 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1659 "   <recipients>"
1660 "       <to>wine-patches@winehq.org</to>"
1661 "   </recipients>"
1662 "   <from name=\"Anonymous\">user@localhost</from>"
1663 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1664 "   <body>"
1665 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1666 "   </body>"
1667 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1668 "</email>";
1669
1670 static const CHAR szEmailXML_16[] =
1671 "<?xml version=\"1.0\"?>"
1672 SZ_EMAIL_DTD
1673 "<email attachments=\"patch1\">"
1674 "   <recipients>"
1675 "       <to>wine-patches@winehq.org</to>"
1676 "   </recipients>"
1677 "   <from name=\"Anonymous\">user@localhost</from>"
1678 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1679 "   <body enc=\"ASCII\">"
1680 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1681 "   </body>"
1682 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1683 "</email>";
1684
1685 static const CHAR szEmailXML_17[] =
1686 "<?xml version=\"1.0\"?>"
1687 SZ_EMAIL_DTD
1688 "<email attachments=\"patch1\" sent=\"true\">"
1689 "   <recipients>"
1690 "       <to>wine-patches@winehq.org</to>"
1691 "   </recipients>"
1692 "   <from name=\"Anonymous\">user@localhost</from>"
1693 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1694 "   <body>"
1695 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1696 "   </body>"
1697 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1698 "</email>";
1699
1700 static const CHAR szEmailXML_18[] =
1701 "<?xml version=\"1.0\"?>"
1702 SZ_EMAIL_DTD
1703 "<email attachments=\"patch1\">"
1704 "   oops"
1705 "   <recipients>"
1706 "       <to>wine-patches@winehq.org</to>"
1707 "   </recipients>"
1708 "   <from name=\"Anonymous\">user@localhost</from>"
1709 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1710 "   <body>"
1711 "       XML_ILLEGAL_TEXT 0xC00CE018"
1712 "   </body>"
1713 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1714 "</email>";
1715
1716 static const CHAR szEmailXML_20[] =
1717 "<?xml version=\"1.0\"?>"
1718 SZ_EMAIL_DTD
1719 "<email>"
1720 "   <recipients>"
1721 "       <to>wine-patches@winehq.org</to>"
1722 "   </recipients>"
1723 "   <from name=\"Anonymous\">user@localhost</from>"
1724 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1725 "   <body>"
1726 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1727 "   </body>"
1728 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1729 "</email>";
1730
1731 static const char xpath_simple_list[] =
1732 "<?xml version=\"1.0\"?>"
1733 "<root>"
1734 "   <a attr1=\"1\" attr2=\"2\" />"
1735 "   <b/>"
1736 "   <c/>"
1737 "   <d/>"
1738 "</root>";
1739
1740 static const char* leading_spaces[] = {
1741     "\n<?xml version=\"1.0\"?><root/>",
1742     " <?xml version=\"1.0\"?><root/>",
1743     "\t<?xml version=\"1.0\"?><root/>",
1744     "\r\n<?xml version=\"1.0\"?><root/>",
1745     "\r<?xml version=\"1.0\"?><root/>",
1746     0
1747 };
1748
1749 static const WCHAR szNonExistentFile[] = {
1750     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1751 };
1752 static const WCHAR szNonExistentAttribute[] = {
1753     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1754 };
1755 static const WCHAR szDocument[] = {
1756     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1757 };
1758
1759 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1760 static WCHAR szdl[] = { 'd','l',0 };
1761 static const WCHAR szvr[] = { 'v','r',0 };
1762 static const WCHAR szlc[] = { 'l','c',0 };
1763 static WCHAR szbs[] = { 'b','s',0 };
1764 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1765 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1766 static const WCHAR szstar[] = { '*',0 };
1767 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1768
1769 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1770 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1771 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1772
1773 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1774 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1775 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1776 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1777                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1778 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1779                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1780
1781 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1782 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1783
1784 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1785                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1786 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1787                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1788                              '!',']',']','>',0};
1789 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1790 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1791
1792 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1793 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1794 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1795
1796 #define expect_bstr_eq_and_free(bstr, expect) { \
1797     BSTR bstrExp = alloc_str_from_narrow(expect); \
1798     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1799     SysFreeString(bstr); \
1800     SysFreeString(bstrExp); \
1801 }
1802
1803 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1804
1805 #define ole_check(expr) { \
1806     HRESULT r = expr; \
1807     ok(r == S_OK, #expr " returned %x\n", r); \
1808 }
1809
1810 #define ole_expect(expr, expect) { \
1811     HRESULT r = expr; \
1812     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1813 }
1814
1815 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1816
1817 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1818 {
1819     void *obj = NULL;
1820     HRESULT hr;
1821
1822     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1823     if (hr != S_OK)
1824         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1825
1826     return obj;
1827 }
1828
1829 #define _create(cls) cls, #cls
1830
1831 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
1832 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1833 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1834 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1835 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1836
1837 static BSTR alloc_str_from_narrow(const char *str)
1838 {
1839     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1840     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1841     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1842     return ret;
1843 }
1844
1845 static BSTR alloced_bstrs[256];
1846 static int alloced_bstrs_count;
1847
1848 static BSTR _bstr_(const char *str)
1849 {
1850     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1851     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1852     return alloced_bstrs[alloced_bstrs_count++];
1853 }
1854
1855 static void free_bstrs(void)
1856 {
1857     int i;
1858     for (i = 0; i < alloced_bstrs_count; i++)
1859         SysFreeString(alloced_bstrs[i]);
1860     alloced_bstrs_count = 0;
1861 }
1862
1863 static VARIANT _variantbstr_(const char *str)
1864 {
1865     VARIANT v;
1866     V_VT(&v) = VT_BSTR;
1867     V_BSTR(&v) = _bstr_(str);
1868     return v;
1869 }
1870
1871 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1872 {
1873     for (;;)
1874     {
1875         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1876         while (*sRight == '\r' || *sRight == '\n') sRight++;
1877         if (*sLeft != *sRight) return FALSE;
1878         if (!*sLeft) return TRUE;
1879         sLeft++;
1880         sRight++;
1881     }
1882 }
1883
1884 static void get_str_for_type(DOMNodeType type, char *buf)
1885 {
1886     switch (type)
1887     {
1888         case NODE_ATTRIBUTE:
1889             strcpy(buf, "A");
1890             break;
1891         case NODE_ELEMENT:
1892             strcpy(buf, "E");
1893             break;
1894         case NODE_DOCUMENT:
1895             strcpy(buf, "D");
1896             break;
1897         case NODE_TEXT:
1898             strcpy(buf, "T");
1899             break;
1900         case NODE_COMMENT:
1901             strcpy(buf, "C");
1902             break;
1903         case NODE_PROCESSING_INSTRUCTION:
1904             strcpy(buf, "P");
1905             break;
1906         default:
1907             wsprintfA(buf, "[%d]", type);
1908     }
1909 }
1910
1911 static int get_node_position(IXMLDOMNode *node)
1912 {
1913     HRESULT r;
1914     int pos = 0;
1915
1916     IXMLDOMNode_AddRef(node);
1917     do
1918     {
1919         IXMLDOMNode *new_node;
1920
1921         pos++;
1922         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1923         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1924         IXMLDOMNode_Release(node);
1925         node = new_node;
1926     } while (r == S_OK);
1927     return pos;
1928 }
1929
1930 static void node_to_string(IXMLDOMNode *node, char *buf)
1931 {
1932     HRESULT r = S_OK;
1933     DOMNodeType type;
1934
1935     if (node == NULL)
1936     {
1937         lstrcpyA(buf, "(null)");
1938         return;
1939     }
1940
1941     IXMLDOMNode_AddRef(node);
1942     while (r == S_OK)
1943     {
1944         IXMLDOMNode *new_node;
1945
1946         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1947         get_str_for_type(type, buf);
1948         buf+=strlen(buf);
1949
1950         if (type == NODE_ATTRIBUTE)
1951         {
1952             BSTR bstr;
1953             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1954             *(buf++) = '\'';
1955             wsprintfA(buf, "%ws", bstr);
1956             buf += strlen(buf);
1957             *(buf++) = '\'';
1958             SysFreeString(bstr);
1959
1960             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1961         }
1962         else
1963         {
1964             r = IXMLDOMNode_get_parentNode(node, &new_node);
1965             wsprintf(buf, "%d", get_node_position(node));
1966             buf += strlen(buf);
1967         }
1968
1969         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1970         IXMLDOMNode_Release(node);
1971         node = new_node;
1972         if (r == S_OK)
1973             *(buf++) = '.';
1974     }
1975
1976     *buf = 0;
1977 }
1978
1979 static char *list_to_string(IXMLDOMNodeList *list)
1980 {
1981     static char buf[4096];
1982     char *pos = buf;
1983     LONG len = 0;
1984     int i;
1985
1986     if (list == NULL)
1987     {
1988         lstrcpyA(buf, "(null)");
1989         return buf;
1990     }
1991     ole_check(IXMLDOMNodeList_get_length(list, &len));
1992     for (i = 0; i < len; i++)
1993     {
1994         IXMLDOMNode *node;
1995         if (i > 0)
1996             *(pos++) = ' ';
1997         ole_check(IXMLDOMNodeList_nextNode(list, &node));
1998         node_to_string(node, pos);
1999         pos += strlen(pos);
2000         IXMLDOMNode_Release(node);
2001     }
2002     *pos = 0;
2003     return buf;
2004 }
2005
2006 #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); }
2007 #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); }
2008
2009 static void test_domdoc( void )
2010 {
2011     HRESULT r, hr;
2012     IXMLDOMDocument *doc;
2013     IXMLDOMParseError *error;
2014     IXMLDOMElement *element = NULL;
2015     IXMLDOMNode *node;
2016     IXMLDOMText *nodetext = NULL;
2017     IXMLDOMComment *node_comment = NULL;
2018     IXMLDOMAttribute *node_attr = NULL;
2019     IXMLDOMNode *nodeChild = NULL;
2020     IXMLDOMProcessingInstruction *nodePI = NULL;
2021     ISupportErrorInfo *support_error = NULL;
2022     VARIANT_BOOL b;
2023     VARIANT var;
2024     BSTR str;
2025     LONG code;
2026     LONG nLength = 0;
2027     WCHAR buff[100];
2028     const char **ptr;
2029
2030     doc = create_document(&IID_IXMLDOMDocument);
2031     if (!doc) return;
2032
2033 if (0)
2034 {
2035     /* crashes on native */
2036     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2037 }
2038
2039     /* try some stupid things */
2040     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2041     EXPECT_HR(hr, S_FALSE);
2042
2043     b = VARIANT_TRUE;
2044     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2045     EXPECT_HR(hr, S_FALSE);
2046     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2047
2048     /* load document with leading spaces */
2049     ptr = leading_spaces;
2050     while (*ptr)
2051     {
2052         b = VARIANT_TRUE;
2053         V_VT(&var) = VT_BSTR;
2054         V_BSTR(&var) = _bstr_(*ptr);
2055         hr = IXMLDOMDocument_load( doc, var, &b);
2056         EXPECT_HR(hr, S_FALSE);
2057         ok( b == VARIANT_FALSE, "got %x\n", b);
2058         ptr++;
2059     }
2060
2061     /* try to load a document from a nonexistent file */
2062     b = VARIANT_TRUE;
2063     str = SysAllocString( szNonExistentFile );
2064     VariantInit(&var);
2065     V_VT(&var) = VT_BSTR;
2066     V_BSTR(&var) = str;
2067
2068     r = IXMLDOMDocument_load( doc, var, &b);
2069     ok( r == S_FALSE, "loadXML succeeded\n");
2070     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2071     SysFreeString( str );
2072
2073     /* try load an empty document */
2074     b = VARIANT_TRUE;
2075     str = SysAllocString( szEmpty );
2076     r = IXMLDOMDocument_loadXML( doc, str, &b );
2077     ok( r == S_FALSE, "loadXML succeeded\n");
2078     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2079     SysFreeString( str );
2080
2081     r = IXMLDOMDocument_get_async( doc, &b );
2082     ok( r == S_OK, "get_async failed (%08x)\n", r);
2083     ok( b == VARIANT_TRUE, "Wrong default value\n");
2084
2085     /* check that there's no document element */
2086     element = NULL;
2087     r = IXMLDOMDocument_get_documentElement( doc, &element );
2088     ok( r == S_FALSE, "should be no document element\n");
2089
2090     /* try finding a node */
2091     node = NULL;
2092     str = SysAllocString( szstr1 );
2093     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2094     ok( r == S_FALSE, "ret %08x\n", r );
2095     SysFreeString( str );
2096
2097     b = VARIANT_TRUE;
2098     str = SysAllocString( szIncomplete );
2099     r = IXMLDOMDocument_loadXML( doc, str, &b );
2100     ok( r == S_FALSE, "loadXML succeeded\n");
2101     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2102     SysFreeString( str );
2103
2104     /* check that there's no document element */
2105     element = (IXMLDOMElement*)1;
2106     r = IXMLDOMDocument_get_documentElement( doc, &element );
2107     ok( r == S_FALSE, "should be no document element\n");
2108     ok( element == NULL, "Element should be NULL\n");
2109
2110     /* test for BSTR handling, pass broken BSTR */
2111     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2112     /* just a big length */
2113     *(DWORD*)buff = 0xf0f0;
2114     b = VARIANT_FALSE;
2115     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2116     ok( r == S_OK, "loadXML failed\n");
2117     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2118
2119     /* loadXML ignores the encoding attribute and always expects Unicode */
2120     b = VARIANT_FALSE;
2121     str = SysAllocString( szComplete6 );
2122     r = IXMLDOMDocument_loadXML( doc, str, &b );
2123     ok( r == S_OK, "loadXML failed\n");
2124     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2125     SysFreeString( str );
2126
2127     /* try a BSTR containing a Windows-1252 document */
2128     b = VARIANT_TRUE;
2129     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2130     r = IXMLDOMDocument_loadXML( doc, str, &b );
2131     ok( r == S_FALSE, "loadXML succeeded\n");
2132     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2133     SysFreeString( str );
2134
2135     /* try to load something valid */
2136     b = VARIANT_FALSE;
2137     str = SysAllocString( szComplete1 );
2138     r = IXMLDOMDocument_loadXML( doc, str, &b );
2139     ok( r == S_OK, "loadXML failed\n");
2140     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2141     SysFreeString( str );
2142
2143     /* check if nodename is correct */
2144     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2145     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2146
2147     str = (BSTR)0xdeadbeef;
2148     r = IXMLDOMDocument_get_baseName( doc, &str );
2149     ok ( r == S_FALSE, "got 0x%08x\n", r);
2150     ok (str == NULL, "got %p\n", str);
2151
2152     /* content doesn't matter here */
2153     str = NULL;
2154     r = IXMLDOMDocument_get_nodeName( doc, &str );
2155     ok ( r == S_OK, "get_nodeName wrong code\n");
2156     ok ( str != NULL, "str is null\n");
2157     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2158     SysFreeString( str );
2159
2160     /* test put_text */
2161     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2162     ok( r == E_FAIL, "ret %08x\n", r );
2163
2164     /* check that there's a document element */
2165     element = NULL;
2166     r = IXMLDOMDocument_get_documentElement( doc, &element );
2167     ok( r == S_OK, "should be a document element\n");
2168     if( element )
2169     {
2170         IObjectIdentity *ident;
2171
2172         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2173         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2174
2175         IXMLDOMElement_Release( element );
2176         element = NULL;
2177     }
2178
2179     /* as soon as we call loadXML again, the document element will disappear */
2180     b = 2;
2181     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2182     ok( r == S_FALSE, "loadXML failed\n");
2183     ok( b == 2, "variant modified\n");
2184     r = IXMLDOMDocument_get_documentElement( doc, &element );
2185     ok( r == S_FALSE, "should be no document element\n");
2186
2187     /* try to load something else simple and valid */
2188     b = VARIANT_FALSE;
2189     str = SysAllocString( szComplete3 );
2190     r = IXMLDOMDocument_loadXML( doc, str, &b );
2191     ok( r == S_OK, "loadXML failed\n");
2192     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2193     SysFreeString( str );
2194
2195     /* try something a little more complicated */
2196     b = FALSE;
2197     str = SysAllocString( szComplete4 );
2198     r = IXMLDOMDocument_loadXML( doc, str, &b );
2199     ok( r == S_OK, "loadXML failed\n");
2200     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2201     SysFreeString( str );
2202
2203     r = IXMLDOMDocument_get_parseError( doc, &error );
2204     ok( r == S_OK, "returns %08x\n", r );
2205
2206     r = IXMLDOMParseError_get_errorCode( error, &code );
2207     ok( r == S_FALSE, "returns %08x\n", r );
2208     ok( code == 0, "code %d\n", code );
2209     IXMLDOMParseError_Release( error );
2210
2211     /* test createTextNode */
2212     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2213     ok( r == S_OK, "returns %08x\n", r );
2214     IXMLDOMText_Release(nodetext);
2215
2216     str = SysAllocString( szOpen );
2217     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2218     ok( r == E_INVALIDARG, "returns %08x\n", r );
2219     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2220     ok( r == S_OK, "returns %08x\n", r );
2221     SysFreeString( str );
2222     if(nodetext)
2223     {
2224         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2225         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2226
2227         /* Text Last Child Checks */
2228         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2229         ok(r == E_INVALIDARG, "ret %08x\n", r );
2230
2231         nodeChild = (IXMLDOMNode*)0x1;
2232         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2233         ok(r == S_FALSE, "ret %08x\n", r );
2234         ok(nodeChild == NULL, "nodeChild not NULL\n");
2235
2236         /* test length property */
2237         r = IXMLDOMText_get_length(nodetext, NULL);
2238         ok(r == E_INVALIDARG, "ret %08x\n", r );
2239
2240         r = IXMLDOMText_get_length(nodetext, &nLength);
2241         ok(r == S_OK, "ret %08x\n", r );
2242         ok(nLength == 4, "expected 4 got %d\n", nLength);
2243
2244         /* put data Tests */
2245         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2246         ok(r == S_OK, "ret %08x\n", r );
2247
2248         /* get data Tests */
2249         r = IXMLDOMText_get_data(nodetext, &str);
2250         ok(r == S_OK, "ret %08x\n", r );
2251         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2252         SysFreeString(str);
2253
2254         /* Confirm XML text is good */
2255         r = IXMLDOMText_get_xml(nodetext, &str);
2256         ok(r == S_OK, "ret %08x\n", r );
2257         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2258         SysFreeString(str);
2259
2260         /* Confirm we get the put_data Text back */
2261         r = IXMLDOMText_get_text(nodetext, &str);
2262         ok(r == S_OK, "ret %08x\n", r );
2263         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2264         SysFreeString(str);
2265
2266         /* test substringData */
2267         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2268         ok(r == E_INVALIDARG, "ret %08x\n", r );
2269
2270         /* test substringData - Invalid offset */
2271         str = (BSTR)&szElement;
2272         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2273         ok(r == E_INVALIDARG, "ret %08x\n", r );
2274         ok( str == NULL, "incorrect string\n");
2275
2276         /* test substringData - Invalid offset */
2277         str = (BSTR)&szElement;
2278         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2279         ok(r == S_FALSE, "ret %08x\n", r );
2280         ok( str == NULL, "incorrect string\n");
2281
2282         /* test substringData - Invalid size */
2283         str = (BSTR)&szElement;
2284         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2285         ok(r == E_INVALIDARG, "ret %08x\n", r );
2286         ok( str == NULL, "incorrect string\n");
2287
2288         /* test substringData - Invalid size */
2289         str = (BSTR)&szElement;
2290         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2291         ok(r == S_FALSE, "ret %08x\n", r );
2292         ok( str == NULL, "incorrect string\n");
2293
2294         /* test substringData - Start of string */
2295         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2296         ok(r == S_OK, "ret %08x\n", r );
2297         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2298         SysFreeString(str);
2299
2300         /* test substringData - Middle of string */
2301         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2302         ok(r == S_OK, "ret %08x\n", r );
2303         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2304         SysFreeString(str);
2305
2306         /* test substringData - End of string */
2307         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2308         ok(r == S_OK, "ret %08x\n", r );
2309         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2310         SysFreeString(str);
2311
2312         /* test appendData */
2313         r = IXMLDOMText_appendData(nodetext, NULL);
2314         ok(r == S_OK, "ret %08x\n", r );
2315
2316         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2317         ok(r == S_OK, "ret %08x\n", r );
2318
2319         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2320         ok(r == S_OK, "ret %08x\n", r );
2321
2322         r = IXMLDOMText_get_text(nodetext, &str);
2323         ok(r == S_OK, "ret %08x\n", r );
2324         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2325         SysFreeString(str);
2326
2327         /* test insertData */
2328         str = SysAllocStringLen(NULL, 0);
2329         r = IXMLDOMText_insertData(nodetext, -1, str);
2330         ok(r == S_OK, "ret %08x\n", r );
2331
2332         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2333         ok(r == S_OK, "ret %08x\n", r );
2334
2335         r = IXMLDOMText_insertData(nodetext, 1000, str);
2336         ok(r == S_OK, "ret %08x\n", r );
2337
2338         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2339         ok(r == S_OK, "ret %08x\n", r );
2340
2341         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2342         ok(r == S_OK, "ret %08x\n", r );
2343
2344         r = IXMLDOMText_insertData(nodetext, 0, str);
2345         ok(r == S_OK, "ret %08x\n", r );
2346         SysFreeString(str);
2347
2348         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2349         ok(r == E_INVALIDARG, "ret %08x\n", r );
2350
2351         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2352         ok(r == E_INVALIDARG, "ret %08x\n", r );
2353
2354         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2355         ok(r == S_OK, "ret %08x\n", r );
2356
2357         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2358         ok(r == S_OK, "ret %08x\n", r );
2359
2360         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2361         ok(r == S_OK, "ret %08x\n", r );
2362
2363         r = IXMLDOMText_get_text(nodetext, &str);
2364         ok(r == S_OK, "ret %08x\n", r );
2365         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2366         SysFreeString(str);
2367
2368         /* delete data */
2369         /* invalid arguments */
2370         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2371         ok(r == E_INVALIDARG, "ret %08x\n", r );
2372
2373         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2374         ok(r == S_OK, "ret %08x\n", r );
2375
2376         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2377         ok(r == E_INVALIDARG, "ret %08x\n", r );
2378
2379         r = IXMLDOMText_get_length(nodetext, &nLength);
2380         ok(r == S_OK, "ret %08x\n", r );
2381         ok(nLength == 43, "expected 43 got %d\n", nLength);
2382
2383         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2384         ok(r == S_OK, "ret %08x\n", r );
2385
2386         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2387         ok(r == E_INVALIDARG, "ret %08x\n", r );
2388
2389         /* delete from start */
2390         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2391         ok(r == S_OK, "ret %08x\n", r );
2392
2393         r = IXMLDOMText_get_length(nodetext, &nLength);
2394         ok(r == S_OK, "ret %08x\n", r );
2395         ok(nLength == 38, "expected 38 got %d\n", nLength);
2396
2397         r = IXMLDOMText_get_text(nodetext, &str);
2398         ok(r == S_OK, "ret %08x\n", r );
2399         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2400         SysFreeString(str);
2401
2402         /* delete from end */
2403         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2404         ok(r == S_OK, "ret %08x\n", r );
2405
2406         r = IXMLDOMText_get_length(nodetext, &nLength);
2407         ok(r == S_OK, "ret %08x\n", r );
2408         ok(nLength == 35, "expected 35 got %d\n", nLength);
2409
2410         r = IXMLDOMText_get_text(nodetext, &str);
2411         ok(r == S_OK, "ret %08x\n", r );
2412         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2413         SysFreeString(str);
2414
2415         /* delete from inside */
2416         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2417         ok(r == S_OK, "ret %08x\n", r );
2418
2419         r = IXMLDOMText_get_length(nodetext, &nLength);
2420         ok(r == S_OK, "ret %08x\n", r );
2421         ok(nLength == 2, "expected 2 got %d\n", nLength);
2422
2423         r = IXMLDOMText_get_text(nodetext, &str);
2424         ok(r == S_OK, "ret %08x\n", r );
2425         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2426         SysFreeString(str);
2427
2428         /* delete whole data ... */
2429         r = IXMLDOMText_get_length(nodetext, &nLength);
2430         ok(r == S_OK, "ret %08x\n", r );
2431
2432         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2433         ok(r == S_OK, "ret %08x\n", r );
2434         /* ... and try again with empty string */
2435         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2436         ok(r == S_OK, "ret %08x\n", r );
2437
2438         /* test put_data */
2439         V_VT(&var) = VT_BSTR;
2440         V_BSTR(&var) = SysAllocString(szstr1);
2441         r = IXMLDOMText_put_nodeValue(nodetext, var);
2442         ok(r == S_OK, "ret %08x\n", r );
2443         VariantClear(&var);
2444
2445         r = IXMLDOMText_get_text(nodetext, &str);
2446         ok(r == S_OK, "ret %08x\n", r );
2447         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2448         SysFreeString(str);
2449
2450         /* test put_data */
2451         V_VT(&var) = VT_I4;
2452         V_I4(&var) = 99;
2453         r = IXMLDOMText_put_nodeValue(nodetext, var);
2454         ok(r == S_OK, "ret %08x\n", r );
2455         VariantClear(&var);
2456
2457         r = IXMLDOMText_get_text(nodetext, &str);
2458         ok(r == S_OK, "ret %08x\n", r );
2459         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2460         SysFreeString(str);
2461
2462         /* ::replaceData() */
2463         V_VT(&var) = VT_BSTR;
2464         V_BSTR(&var) = SysAllocString(szstr1);
2465         r = IXMLDOMText_put_nodeValue(nodetext, var);
2466         ok(r == S_OK, "ret %08x\n", r );
2467         VariantClear(&var);
2468
2469         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2470         ok(r == E_INVALIDARG, "ret %08x\n", r );
2471         r = IXMLDOMText_get_text(nodetext, &str);
2472         ok(r == S_OK, "ret %08x\n", r );
2473         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2474         SysFreeString(str);
2475
2476         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2477         ok(r == S_OK, "ret %08x\n", r );
2478         r = IXMLDOMText_get_text(nodetext, &str);
2479         ok(r == S_OK, "ret %08x\n", r );
2480         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2481         SysFreeString(str);
2482
2483         /* NULL pointer means delete */
2484         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2485         ok(r == S_OK, "ret %08x\n", r );
2486         r = IXMLDOMText_get_text(nodetext, &str);
2487         ok(r == S_OK, "ret %08x\n", r );
2488         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2489         SysFreeString(str);
2490
2491         /* empty string means delete */
2492         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2493         ok(r == S_OK, "ret %08x\n", r );
2494         r = IXMLDOMText_get_text(nodetext, &str);
2495         ok(r == S_OK, "ret %08x\n", r );
2496         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2497         SysFreeString(str);
2498
2499         /* zero count means insert */
2500         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2501         ok(r == S_OK, "ret %08x\n", r );
2502         r = IXMLDOMText_get_text(nodetext, &str);
2503         ok(r == S_OK, "ret %08x\n", r );
2504         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2505         SysFreeString(str);
2506
2507         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2508         ok(r == S_OK, "ret %08x\n", r );
2509
2510         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2511         ok(r == S_OK, "ret %08x\n", r );
2512         r = IXMLDOMText_get_text(nodetext, &str);
2513         ok(r == S_OK, "ret %08x\n", r );
2514         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2515         SysFreeString(str);
2516
2517         /* nonempty string, count greater than its length */
2518         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2519         ok(r == S_OK, "ret %08x\n", r );
2520         r = IXMLDOMText_get_text(nodetext, &str);
2521         ok(r == S_OK, "ret %08x\n", r );
2522         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2523         SysFreeString(str);
2524
2525         /* nonempty string, count less than its length */
2526         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2527         ok(r == S_OK, "ret %08x\n", r );
2528         r = IXMLDOMText_get_text(nodetext, &str);
2529         ok(r == S_OK, "ret %08x\n", r );
2530         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2531         SysFreeString(str);
2532
2533         IXMLDOMText_Release( nodetext );
2534     }
2535
2536     /* test Create Comment */
2537     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2538     ok( r == E_INVALIDARG, "returns %08x\n", r );
2539     node_comment = (IXMLDOMComment*)0x1;
2540
2541     /* empty comment */
2542     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2543     ok( r == S_OK, "returns %08x\n", r );
2544     str = (BSTR)0x1;
2545     r = IXMLDOMComment_get_data(node_comment, &str);
2546     ok( r == S_OK, "returns %08x\n", r );
2547     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2548     IXMLDOMComment_Release(node_comment);
2549     SysFreeString(str);
2550
2551     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2552     ok( r == S_OK, "returns %08x\n", r );
2553     str = (BSTR)0x1;
2554     r = IXMLDOMComment_get_data(node_comment, &str);
2555     ok( r == S_OK, "returns %08x\n", r );
2556     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2557     IXMLDOMComment_Release(node_comment);
2558     SysFreeString(str);
2559
2560     str = SysAllocString(szComment);
2561     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2562     SysFreeString(str);
2563     ok( r == S_OK, "returns %08x\n", r );
2564     if(node_comment)
2565     {
2566         /* Last Child Checks */
2567         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2568         ok(r == E_INVALIDARG, "ret %08x\n", r );
2569
2570         nodeChild = (IXMLDOMNode*)0x1;
2571         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2572         ok(r == S_FALSE, "ret %08x\n", r );
2573         ok(nodeChild == NULL, "pLastChild not NULL\n");
2574
2575         /* baseName */
2576         str = (BSTR)0xdeadbeef;
2577         IXMLDOMComment_get_baseName(node_comment, &str);
2578         ok(r == S_FALSE, "ret %08x\n", r );
2579         ok(str == NULL, "Expected NULL\n");
2580
2581         IXMLDOMComment_Release( node_comment );
2582     }
2583
2584     /* test Create Attribute */
2585     str = SysAllocString(szAttribute);
2586     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2587     ok( r == E_INVALIDARG, "returns %08x\n", r );
2588     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2589     ok( r == S_OK, "returns %08x\n", r );
2590     IXMLDOMText_Release( node_attr);
2591     SysFreeString(str);
2592
2593     /* test Processing Instruction */
2594     str = SysAllocStringLen(NULL, 0);
2595     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2596     ok( r == E_INVALIDARG, "returns %08x\n", r );
2597     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2598     ok( r == E_FAIL, "returns %08x\n", r );
2599     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2600     ok( r == E_FAIL, "returns %08x\n", r );
2601     SysFreeString(str);
2602
2603     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2604     ok( r == S_OK, "returns %08x\n", r );
2605     if(nodePI)
2606     {
2607         /* Last Child Checks */
2608         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2609         ok(r == E_INVALIDARG, "ret %08x\n", r );
2610
2611         nodeChild = (IXMLDOMNode*)0x1;
2612         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2613         ok(r == S_FALSE, "ret %08x\n", r );
2614         ok(nodeChild == NULL, "nodeChild not NULL\n");
2615
2616         /* test nodeName */
2617         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2618         ok(r == S_OK, "ret %08x\n", r );
2619         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2620         SysFreeString(str);
2621
2622         /* test baseName */
2623         str = (BSTR)0x1;
2624         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2625         ok(r == S_OK, "ret %08x\n", r );
2626         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2627         SysFreeString(str);
2628
2629         /* test Target */
2630         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2631         ok(r == S_OK, "ret %08x\n", r );
2632         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2633         SysFreeString(str);
2634
2635         /* test get_nodeValue */
2636         r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
2637         ok(r == S_OK, "ret %08x\n", r );
2638         ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2639         VariantClear(&var);
2640
2641         /* test get_data */
2642         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2643         ok(r == S_OK, "ret %08x\n", r );
2644         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2645         SysFreeString(str);
2646
2647         /* test put_data */
2648         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2649         ok(r == E_FAIL, "ret %08x\n", r );
2650
2651         /* test put_data */
2652         V_VT(&var) = VT_BSTR;
2653         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2654         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2655         ok(r == E_FAIL, "ret %08x\n", r );
2656         VariantClear(&var);
2657
2658         /* test get nodeName */
2659         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2660         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2661         ok(r == S_OK, "ret %08x\n", r );
2662         SysFreeString(str);
2663
2664         IXMLDOMProcessingInstruction_Release(nodePI);
2665     }
2666
2667     r = IXMLDOMDocument_QueryInterface( doc, &IID_ISupportErrorInfo, (void**)&support_error );
2668     ok( r == S_OK, "ret %08x\n", r );
2669     if(r == S_OK)
2670     {
2671         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMDocument );
2672         todo_wine ok( r == S_OK, "ret %08x\n", r );
2673         ISupportErrorInfo_Release( support_error );
2674     }
2675
2676     r = IXMLDOMDocument_Release( doc );
2677     ok( r == 0, "document ref count incorrect\n");
2678
2679     free_bstrs();
2680 }
2681
2682 static void test_persiststreaminit(void)
2683 {
2684     IXMLDOMDocument *doc;
2685     IPersistStreamInit *streaminit;
2686     HRESULT hr;
2687
2688     doc = create_document(&IID_IXMLDOMDocument);
2689     if (!doc) return;
2690
2691     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2692     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2693
2694     hr = IPersistStreamInit_InitNew(streaminit);
2695     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2696
2697     IXMLDOMDocument_Release(doc);
2698 }
2699
2700 static void test_domnode( void )
2701 {
2702     HRESULT r;
2703     IXMLDOMDocument *doc, *owner = NULL;
2704     IXMLDOMElement *element = NULL;
2705     IXMLDOMNamedNodeMap *map = NULL;
2706     IXMLDOMNode *node = NULL, *next = NULL;
2707     IXMLDOMNodeList *list = NULL;
2708     IXMLDOMAttribute *attr = NULL;
2709     DOMNodeType type = NODE_INVALID;
2710     VARIANT_BOOL b;
2711     BSTR str;
2712     VARIANT var;
2713     LONG count;
2714
2715     doc = create_document(&IID_IXMLDOMDocument);
2716     if (!doc) return;
2717
2718     b = FALSE;
2719     str = SysAllocString( szComplete4 );
2720     r = IXMLDOMDocument_loadXML( doc, str, &b );
2721     ok( r == S_OK, "loadXML failed\n");
2722     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2723     SysFreeString( str );
2724
2725     EXPECT_CHILDREN(doc);
2726
2727     r = IXMLDOMDocument_get_documentElement( doc, &element );
2728     ok( r == S_OK, "should be a document element\n");
2729     ok( element != NULL, "should be an element\n");
2730
2731     VariantInit(&var);
2732     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2733
2734     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2735     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2736
2737     r = IXMLDOMNode_get_nodeValue( doc, &var );
2738     ok( r == S_FALSE, "nextNode returned wrong code\n");
2739     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2740     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2741
2742     if (element)
2743     {
2744         owner = NULL;
2745         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2746         ok( r == S_OK, "get_ownerDocument return code\n");
2747         ok( owner != doc, "get_ownerDocument return\n");
2748         IXMLDOMDocument_Release(owner);
2749
2750         type = NODE_INVALID;
2751         r = IXMLDOMNode_get_nodeType( element, &type);
2752         ok( r == S_OK, "got %08x\n", r);
2753         ok( type == NODE_ELEMENT, "node not an element\n");
2754
2755         str = NULL;
2756         r = IXMLDOMNode_get_baseName( element, &str );
2757         ok( r == S_OK, "get_baseName returned wrong code\n");
2758         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2759         SysFreeString(str);
2760
2761         /* check if nodename is correct */
2762         r = IXMLDOMElement_get_nodeName( element, NULL );
2763         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2764
2765         /* content doesn't matter here */
2766         str = NULL;
2767         r = IXMLDOMElement_get_nodeName( element, &str );
2768         ok ( r == S_OK, "get_nodeName wrong code\n");
2769         ok ( str != NULL, "str is null\n");
2770         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2771         SysFreeString( str );
2772
2773         str = SysAllocString( szNonExistentFile );      
2774         V_VT(&var) = VT_I4;
2775         V_I4(&var) = 0x1234;
2776         r = IXMLDOMElement_getAttribute( element, str, &var );
2777         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2778         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2779         VariantClear(&var);
2780
2781         r = IXMLDOMElement_getAttributeNode( element, str, NULL);
2782         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
2783
2784         attr = (IXMLDOMAttribute*)0xdeadbeef;
2785         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2786         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
2787         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
2788         SysFreeString( str );
2789
2790         attr = (IXMLDOMAttribute*)0xdeadbeef;
2791         str = SysAllocString( szNonExistentAttribute );
2792         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2793         ok( r == S_FALSE, "getAttributeNode ret %08x\n", r );
2794         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
2795         SysFreeString( str );
2796
2797         str = SysAllocString( szdl );   
2798         V_VT(&var) = VT_I4;
2799         V_I4(&var) = 0x1234;
2800         r = IXMLDOMElement_getAttribute( element, str, &var );
2801         ok( r == S_OK, "getAttribute ret %08x\n", r );
2802         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2803         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2804         VariantClear( &var );
2805
2806         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2807         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2808
2809         r = IXMLDOMElement_getAttribute( element, str, NULL );
2810         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2811
2812         attr = NULL;
2813         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2814         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2815         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2816         if (attr)
2817         {
2818             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2819             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2820
2821             /* attribute doesn't have a parent in msxml interpretation */
2822             node = (IXMLDOMNode*)0xdeadbeef;
2823             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2824             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2825             ok( node == NULL, "Expected NULL, got %p\n", node );
2826
2827             IXMLDOMAttribute_Release(attr);
2828         }
2829
2830         SysFreeString( str );
2831
2832         r = IXMLDOMElement_get_attributes( element, &map );
2833         ok( r == S_OK, "get_attributes returned wrong code\n");
2834         ok( map != NULL, "should be attributes\n");
2835
2836         EXPECT_CHILDREN(element);
2837     }
2838     else
2839         ok( FALSE, "no element\n");
2840
2841     if (map)
2842     {
2843         ISupportErrorInfo *support_error;
2844         r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (void**)&support_error );
2845         ok( r == S_OK, "ret %08x\n", r );
2846
2847         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
2848 todo_wine
2849 {
2850         ok( r == S_OK, "ret %08x\n", r );
2851 }
2852         ISupportErrorInfo_Release( support_error );
2853
2854         str = SysAllocString( szdl );
2855         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2856         ok( r == S_OK, "getNamedItem returned wrong code\n");
2857         ok( node != NULL, "should be attributes\n");
2858         IXMLDOMNode_Release(node);
2859         SysFreeString( str );
2860
2861         str = SysAllocString( szdl );
2862         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2863         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2864         SysFreeString( str );
2865
2866         /* something that isn't in szComplete4 */
2867         str = SysAllocString( szOpen );
2868         node = (IXMLDOMNode *) 1;
2869         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2870         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2871         ok( node == NULL, "getNamedItem should have returned NULL\n");
2872         SysFreeString( str );
2873
2874         /* test indexed access of attributes */
2875         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2876         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2877
2878         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2879         ok ( r == S_OK, "get_length wrong code\n");
2880         ok ( count == 1, "get_length != 1\n");
2881
2882         node = NULL;
2883         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2884         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2885         ok ( node == NULL, "there is no node\n");
2886
2887         node = NULL;
2888         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2889         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2890         ok ( node == NULL, "there is no attribute\n");
2891
2892         node = NULL;
2893         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2894         ok ( r == S_OK, "get_item (0) wrong code\n");
2895         ok ( node != NULL, "should be attribute\n");
2896
2897         r = IXMLDOMNode_get_nodeName( node, NULL );
2898         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2899
2900         /* content doesn't matter here */
2901         str = NULL;
2902         r = IXMLDOMNode_get_nodeName( node, &str );
2903         ok ( r == S_OK, "get_nodeName wrong code\n");
2904         ok ( str != NULL, "str is null\n");
2905         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2906         SysFreeString( str );
2907         IXMLDOMNode_Release( node );
2908
2909         /* test sequential access of attributes */
2910         node = NULL;
2911         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2912         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2913         ok ( node != NULL, "nextNode, should be attribute\n");
2914         IXMLDOMNode_Release( node );
2915
2916         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2917         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2918         ok ( node == NULL, "nextNode, there is no attribute\n");
2919
2920         r = IXMLDOMNamedNodeMap_reset( map );
2921         ok ( r == S_OK, "reset should return S_OK\n");
2922
2923         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2924         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2925         ok ( node != NULL, "nextNode, should be attribute\n");
2926     }
2927     else
2928         ok( FALSE, "no map\n");
2929
2930     if (node)
2931     {
2932         type = NODE_INVALID;
2933         r = IXMLDOMNode_get_nodeType( node, &type);
2934         ok( r == S_OK, "getNamedItem returned wrong code\n");
2935         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2936
2937         str = NULL;
2938         r = IXMLDOMNode_get_baseName( node, NULL );
2939         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2940
2941         str = NULL;
2942         r = IXMLDOMNode_get_baseName( node, &str );
2943         ok( r == S_OK, "get_baseName returned wrong code\n");
2944         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2945         SysFreeString( str );
2946
2947         r = IXMLDOMNode_get_nodeValue( node, &var );
2948         ok( r == S_OK, "returns %08x\n", r );
2949         ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
2950         ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
2951         VariantClear(&var);
2952
2953         r = IXMLDOMNode_get_childNodes( node, NULL );
2954         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2955
2956         r = IXMLDOMNode_get_childNodes( node, &list );
2957         ok( r == S_OK, "get_childNodes returned wrong code\n");
2958
2959         if (list)
2960         {
2961             r = IXMLDOMNodeList_nextNode( list, &next );
2962             ok( r == S_OK, "nextNode returned wrong code\n");
2963         }
2964         else
2965             ok( FALSE, "no childlist\n");
2966
2967         if (next)
2968         {
2969             EXPECT_NO_CHILDREN(next);
2970
2971             type = NODE_INVALID;
2972             r = IXMLDOMNode_get_nodeType( next, &type);
2973             ok( r == S_OK, "getNamedItem returned wrong code\n");
2974             ok( type == NODE_TEXT, "node not text\n");
2975
2976             str = (BSTR) 1;
2977             r = IXMLDOMNode_get_baseName( next, &str );
2978             ok( r == S_FALSE, "get_baseName returned wrong code\n");
2979             ok( str == NULL, "basename was wrong\n");
2980             SysFreeString(str);
2981         }
2982         else
2983             ok( FALSE, "no next\n");
2984
2985         if (next)
2986             IXMLDOMNode_Release( next );
2987         next = NULL;
2988         if (list)
2989             IXMLDOMNodeList_Release( list );
2990         list = NULL;
2991         if (node)
2992             IXMLDOMNode_Release( node );
2993     }
2994     else
2995         ok( FALSE, "no node\n");
2996     node = NULL;
2997
2998     if (map)
2999         IXMLDOMNamedNodeMap_Release( map );
3000
3001     /* now traverse the tree from the root element */
3002     if (element)
3003     {
3004         r = IXMLDOMNode_get_childNodes( element, &list );
3005         ok( r == S_OK, "get_childNodes returned wrong code\n");
3006
3007         /* using get_item for child list doesn't advance the position */
3008         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3009         expect_node(node, "E2.E2.D1");
3010         IXMLDOMNode_Release(node);
3011         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3012         expect_node(node, "E1.E2.D1");
3013         IXMLDOMNode_Release(node);
3014         ole_check(IXMLDOMNodeList_reset(list));
3015
3016         IXMLDOMNodeList_AddRef(list);
3017         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3018         ole_check(IXMLDOMNodeList_reset(list));
3019
3020         node = (void*)0xdeadbeef;
3021         str = SysAllocString(szdl);
3022         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3023         SysFreeString(str);
3024         ok( r == S_FALSE, "ret %08x\n", r );
3025         ok( node == NULL, "node %p\n", node );
3026
3027         str = SysAllocString(szbs);
3028         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3029         SysFreeString(str);
3030         ok( r == S_OK, "ret %08x\n", r );
3031         r = IXMLDOMNode_Release( node );
3032         ok( r == 0, "ret %08x\n", r );
3033     }
3034     else
3035         ok( FALSE, "no element\n");
3036
3037     if (list)
3038     {
3039         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3040         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3041
3042         r = IXMLDOMNodeList_get_length(list, NULL);
3043         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3044
3045         r = IXMLDOMNodeList_get_length( list, &count );
3046         ok( r == S_OK, "get_length returns %08x\n", r );
3047         ok( count == 4, "get_length got %d\n", count );
3048
3049         r = IXMLDOMNodeList_nextNode(list, NULL);
3050         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3051
3052         r = IXMLDOMNodeList_nextNode( list, &node );
3053         ok( r == S_OK, "nextNode returned wrong code\n");
3054     }
3055     else
3056         ok( FALSE, "no list\n");
3057
3058     if (node)
3059     {
3060         type = NODE_INVALID;
3061         r = IXMLDOMNode_get_nodeType( node, &type);
3062         ok( r == S_OK, "getNamedItem returned wrong code\n");
3063         ok( type == NODE_ELEMENT, "node not text\n");
3064
3065         VariantInit(&var);
3066         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
3067         r = IXMLDOMNode_get_nodeValue( node, &var );
3068         ok( r == S_FALSE, "nextNode returned wrong code\n");
3069         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
3070         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
3071
3072         r = IXMLDOMNode_hasChildNodes( node, NULL );
3073         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3074
3075         EXPECT_CHILDREN(node);
3076
3077         str = NULL;
3078         r = IXMLDOMNode_get_baseName( node, &str );
3079         ok( r == S_OK, "get_baseName returned wrong code\n");
3080         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3081         SysFreeString(str);
3082     }
3083     else
3084         ok( FALSE, "no node\n");
3085
3086     if (node)
3087         IXMLDOMNode_Release( node );
3088     if (list)
3089         IXMLDOMNodeList_Release( list );
3090     if (element)
3091         IXMLDOMElement_Release( element );
3092
3093     b = FALSE;
3094     str = SysAllocString( szComplete5 );
3095     r = IXMLDOMDocument_loadXML( doc, str, &b );
3096     ok( r == S_OK, "loadXML failed\n");
3097     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3098     SysFreeString( str );
3099
3100     EXPECT_CHILDREN(doc);
3101
3102     r = IXMLDOMDocument_get_documentElement( doc, &element );
3103     ok( r == S_OK, "should be a document element\n");
3104     ok( element != NULL, "should be an element\n");
3105
3106     if (element)
3107     {
3108         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3109         BSTR tag = NULL;
3110
3111         /* check if the tag is correct */
3112         r = IXMLDOMElement_get_tagName( element, &tag );
3113         ok( r == S_OK, "couldn't get tag name\n");
3114         ok( tag != NULL, "tag was null\n");
3115         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3116         SysFreeString( tag );
3117     }
3118
3119     if (element)
3120         IXMLDOMElement_Release( element );
3121     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3122 }
3123
3124 static void test_refs(void)
3125 {
3126     HRESULT r;
3127     BSTR str;
3128     VARIANT_BOOL b;
3129     IXMLDOMDocument *doc;
3130     IXMLDOMElement *element = NULL;
3131     IXMLDOMNode *node = NULL, *node2;
3132     IXMLDOMNodeList *node_list = NULL;
3133     LONG ref;
3134     IUnknown *unk, *unk2;
3135
3136     doc = create_document(&IID_IXMLDOMDocument);
3137     if (!doc) return;
3138
3139     EXPECT_REF(doc, 1);
3140     ref = IXMLDOMDocument_Release(doc);
3141     ok( ref == 0, "ref %d\n", ref);
3142
3143     doc = create_document(&IID_IXMLDOMDocument);
3144     if (!doc) return;
3145
3146     str = SysAllocString( szComplete4 );
3147     r = IXMLDOMDocument_loadXML( doc, str, &b );
3148     ok( r == S_OK, "loadXML failed\n");
3149     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3150     SysFreeString( str );
3151
3152     EXPECT_REF(doc, 1);
3153     IXMLDOMDocument_AddRef( doc );
3154     EXPECT_REF(doc, 2);
3155     IXMLDOMDocument_AddRef( doc );
3156     EXPECT_REF(doc, 3);
3157
3158     IXMLDOMDocument_Release( doc );
3159     IXMLDOMDocument_Release( doc );
3160
3161     r = IXMLDOMDocument_get_documentElement( doc, &element );
3162     ok( r == S_OK, "should be a document element\n");
3163     ok( element != NULL, "should be an element\n");
3164
3165     EXPECT_REF(doc, 1);
3166     todo_wine EXPECT_REF(element, 2);
3167
3168     IXMLDOMElement_AddRef(element);
3169     todo_wine EXPECT_REF(element, 3);
3170     IXMLDOMElement_Release(element);
3171
3172     r = IXMLDOMElement_get_childNodes( element, &node_list );
3173     ok( r == S_OK, "rets %08x\n", r);
3174
3175     todo_wine EXPECT_REF(element, 2);
3176     EXPECT_REF(node_list, 1);
3177
3178     IXMLDOMNodeList_get_item( node_list, 0, &node );
3179     ok( r == S_OK, "rets %08x\n", r);
3180     EXPECT_REF(node_list, 1);
3181     EXPECT_REF(node, 1);
3182
3183     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3184     ok( r == S_OK, "rets %08x\n", r);
3185     EXPECT_REF(node_list, 1);
3186     EXPECT_REF(node2, 1);
3187
3188     ref = IXMLDOMNode_Release( node );
3189     ok( ref == 0, "ref %d\n", ref );
3190     ref = IXMLDOMNode_Release( node2 );
3191     ok( ref == 0, "ref %d\n", ref );
3192
3193     ref = IXMLDOMNodeList_Release( node_list );
3194     ok( ref == 0, "ref %d\n", ref );
3195
3196     ok( node != node2, "node %p node2 %p\n", node, node2 );
3197
3198     ref = IXMLDOMDocument_Release( doc );
3199     ok( ref == 0, "ref %d\n", ref );
3200
3201     todo_wine EXPECT_REF(element, 2);
3202
3203     /* IUnknown must be unique however we obtain it */
3204     r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (void**)&unk );
3205     ok( r == S_OK, "rets %08x\n", r );
3206     EXPECT_REF(element, 2);
3207     r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (void**)&node );
3208     ok( r == S_OK, "rets %08x\n", r );
3209     todo_wine EXPECT_REF(element, 2);
3210     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk2 );
3211     ok( r == S_OK, "rets %08x\n", r );
3212     todo_wine EXPECT_REF(element, 2);
3213     ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
3214     todo_wine ok( element != (void*)node, "node %p element %p\n", node, element );
3215
3216     IUnknown_Release( unk2 );
3217     IUnknown_Release( unk );
3218     IXMLDOMNode_Release( node );
3219     todo_wine EXPECT_REF(element, 2);
3220
3221     IXMLDOMElement_Release( element );
3222 }
3223
3224 static void test_create(void)
3225 {
3226     static const WCHAR szOne[] = {'1',0};
3227     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3228     HRESULT r;
3229     VARIANT var;
3230     BSTR str, name;
3231     IXMLDOMDocument *doc;
3232     IXMLDOMElement *element;
3233     IXMLDOMComment *comment;
3234     IXMLDOMText *text;
3235     IXMLDOMCDATASection *cdata;
3236     IXMLDOMNode *root, *node, *child;
3237     IXMLDOMNamedNodeMap *attr_map;
3238     IUnknown *unk;
3239     LONG ref;
3240     LONG num;
3241
3242     doc = create_document(&IID_IXMLDOMDocument);
3243     if (!doc) return;
3244
3245     EXPECT_REF(doc, 1);
3246
3247     /* types not supported for creation */
3248     V_VT(&var) = VT_I1;
3249     V_I1(&var) = NODE_DOCUMENT;
3250     node = (IXMLDOMNode*)0x1;
3251     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3252     ok( r == E_INVALIDARG, "returns %08x\n", r );
3253     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3254
3255     V_VT(&var) = VT_I1;
3256     V_I1(&var) = NODE_DOCUMENT_TYPE;
3257     node = (IXMLDOMNode*)0x1;
3258     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3259     ok( r == E_INVALIDARG, "returns %08x\n", r );
3260     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3261
3262     V_VT(&var) = VT_I1;
3263     V_I1(&var) = NODE_ENTITY;
3264     node = (IXMLDOMNode*)0x1;
3265     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3266     ok( r == E_INVALIDARG, "returns %08x\n", r );
3267     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3268
3269     V_VT(&var) = VT_I1;
3270     V_I1(&var) = NODE_NOTATION;
3271     node = (IXMLDOMNode*)0x1;
3272     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3273     ok( r == E_INVALIDARG, "returns %08x\n", r );
3274     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3275
3276     /* NODE_COMMENT */
3277     V_VT(&var) = VT_I1;
3278     V_I1(&var) = NODE_COMMENT;
3279     node = NULL;
3280     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3281     ok( r == S_OK, "returns %08x\n", r );
3282     ok( node != NULL, "\n");
3283
3284     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3285     ok( r == S_OK, "returns %08x\n", r );
3286     IXMLDOMNode_Release(node);
3287
3288     str = NULL;
3289     r = IXMLDOMComment_get_data(comment, &str);
3290     ok( r == S_OK, "returns %08x\n", r );
3291     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3292     IXMLDOMComment_Release(comment);
3293     SysFreeString(str);
3294
3295     node = (IXMLDOMNode*)0x1;
3296     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3297     ok( r == S_OK, "returns %08x\n", r );
3298
3299     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3300     ok( r == S_OK, "returns %08x\n", r );
3301     IXMLDOMNode_Release(node);
3302
3303     str = NULL;
3304     r = IXMLDOMComment_get_data(comment, &str);
3305     ok( r == S_OK, "returns %08x\n", r );
3306     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3307     IXMLDOMComment_Release(comment);
3308     SysFreeString(str);
3309
3310     node = (IXMLDOMNode*)0x1;
3311     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3312     ok( r == S_OK, "returns %08x\n", r );
3313
3314     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3315     ok( r == S_OK, "returns %08x\n", r );
3316     IXMLDOMNode_Release(node);
3317
3318     str = NULL;
3319     r = IXMLDOMComment_get_data(comment, &str);
3320     ok( r == S_OK, "returns %08x\n", r );
3321     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3322     IXMLDOMComment_Release(comment);
3323     SysFreeString(str);
3324
3325     /* NODE_TEXT */
3326     V_VT(&var) = VT_I1;
3327     V_I1(&var) = NODE_TEXT;
3328     node = NULL;
3329     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3330     ok( r == S_OK, "returns %08x\n", r );
3331     ok( node != NULL, "\n");
3332
3333     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3334     ok( r == S_OK, "returns %08x\n", r );
3335     IXMLDOMNode_Release(node);
3336
3337     str = NULL;
3338     r = IXMLDOMText_get_data(text, &str);
3339     ok( r == S_OK, "returns %08x\n", r );
3340     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3341     IXMLDOMText_Release(text);
3342     SysFreeString(str);
3343
3344     node = (IXMLDOMNode*)0x1;
3345     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3346     ok( r == S_OK, "returns %08x\n", r );
3347
3348     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3349     ok( r == S_OK, "returns %08x\n", r );
3350     IXMLDOMNode_Release(node);
3351
3352     str = NULL;
3353     r = IXMLDOMText_get_data(text, &str);
3354     ok( r == S_OK, "returns %08x\n", r );
3355     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3356     IXMLDOMText_Release(text);
3357     SysFreeString(str);
3358
3359     node = (IXMLDOMNode*)0x1;
3360     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3361     ok( r == S_OK, "returns %08x\n", r );
3362
3363     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3364     ok( r == S_OK, "returns %08x\n", r );
3365     IXMLDOMNode_Release(node);
3366
3367     str = NULL;
3368     r = IXMLDOMText_get_data(text, &str);
3369     ok( r == S_OK, "returns %08x\n", r );
3370     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3371     IXMLDOMText_Release(text);
3372     SysFreeString(str);
3373
3374     /* NODE_CDATA_SECTION */
3375     V_VT(&var) = VT_I1;
3376     V_I1(&var) = NODE_CDATA_SECTION;
3377     node = NULL;
3378     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3379     ok( r == S_OK, "returns %08x\n", r );
3380     ok( node != NULL, "\n");
3381
3382     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3383     ok( r == S_OK, "returns %08x\n", r );
3384     IXMLDOMNode_Release(node);
3385
3386     str = NULL;
3387     r = IXMLDOMCDATASection_get_data(cdata, &str);
3388     ok( r == S_OK, "returns %08x\n", r );
3389     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3390     IXMLDOMCDATASection_Release(cdata);
3391     SysFreeString(str);
3392
3393     node = (IXMLDOMNode*)0x1;
3394     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3395     ok( r == S_OK, "returns %08x\n", r );
3396
3397     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3398     ok( r == S_OK, "returns %08x\n", r );
3399     IXMLDOMNode_Release(node);
3400
3401     str = NULL;
3402     r = IXMLDOMCDATASection_get_data(cdata, &str);
3403     ok( r == S_OK, "returns %08x\n", r );
3404     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3405     IXMLDOMCDATASection_Release(cdata);
3406     SysFreeString(str);
3407
3408     node = (IXMLDOMNode*)0x1;
3409     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3410     ok( r == S_OK, "returns %08x\n", r );
3411
3412     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3413     ok( r == S_OK, "returns %08x\n", r );
3414     IXMLDOMNode_Release(node);
3415
3416     str = NULL;
3417     r = IXMLDOMCDATASection_get_data(cdata, &str);
3418     ok( r == S_OK, "returns %08x\n", r );
3419     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3420     IXMLDOMCDATASection_Release(cdata);
3421     SysFreeString(str);
3422
3423     /* NODE_ATTRIBUTE */
3424     V_VT(&var) = VT_I1;
3425     V_I1(&var) = NODE_ATTRIBUTE;
3426     node = (IXMLDOMNode*)0x1;
3427     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3428     ok( r == E_FAIL, "returns %08x\n", r );
3429     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3430
3431     V_VT(&var) = VT_I1;
3432     V_I1(&var) = NODE_ATTRIBUTE;
3433     node = (IXMLDOMNode*)0x1;
3434     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3435     ok( r == E_FAIL, "returns %08x\n", r );
3436     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3437
3438     V_VT(&var) = VT_I1;
3439     V_I1(&var) = NODE_ATTRIBUTE;
3440     str = SysAllocString( szlc );
3441     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3442     ok( r == S_OK, "returns %08x\n", r );
3443     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3444     SysFreeString(str);
3445
3446     /* a name is required for attribute, try a BSTR with first null wchar */
3447     V_VT(&var) = VT_I1;
3448     V_I1(&var) = NODE_ATTRIBUTE;
3449     str = SysAllocString( szstr1 );
3450     str[0] = 0;
3451     node = (IXMLDOMNode*)0x1;
3452     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3453     ok( r == E_FAIL, "returns %08x\n", r );
3454     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3455     SysFreeString(str);
3456
3457     /* NODE_PROCESSING_INSTRUCTION */
3458     V_VT(&var) = VT_I1;
3459     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3460     node = (IXMLDOMNode*)0x1;
3461     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3462     ok( r == E_FAIL, "returns %08x\n", r );
3463     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3464
3465     V_VT(&var) = VT_I1;
3466     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3467     node = (IXMLDOMNode*)0x1;
3468     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3469     ok( r == E_FAIL, "returns %08x\n", r );
3470     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3471
3472     V_VT(&var) = VT_I1;
3473     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3474     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3475     ok( r == E_INVALIDARG, "returns %08x\n", r );
3476
3477     /* NODE_ENTITY_REFERENCE */
3478     V_VT(&var) = VT_I1;
3479     V_I1(&var) = NODE_ENTITY_REFERENCE;
3480     node = (IXMLDOMNode*)0x1;
3481     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3482     ok( r == E_FAIL, "returns %08x\n", r );
3483     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3484
3485     V_VT(&var) = VT_I1;
3486     V_I1(&var) = NODE_ENTITY_REFERENCE;
3487     node = (IXMLDOMNode*)0x1;
3488     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3489     ok( r == E_FAIL, "returns %08x\n", r );
3490     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3491
3492     /* NODE_ELEMENT */
3493     V_VT(&var) = VT_I1;
3494     V_I1(&var) = NODE_ELEMENT;
3495     node = (IXMLDOMNode*)0x1;
3496     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3497     ok( r == E_FAIL, "returns %08x\n", r );
3498     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3499
3500     V_VT(&var) = VT_I1;
3501     V_I1(&var) = NODE_ELEMENT;
3502     node = (IXMLDOMNode*)0x1;
3503     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3504     ok( r == E_FAIL, "returns %08x\n", r );
3505     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3506
3507     V_VT(&var) = VT_I1;
3508     V_I1(&var) = NODE_ELEMENT;
3509     str = SysAllocString( szlc );
3510     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3511     ok( r == S_OK, "returns %08x\n", r );
3512     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3513
3514     V_VT(&var) = VT_I1;
3515     V_I1(&var) = NODE_ELEMENT;
3516     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3517     ok( r == E_INVALIDARG, "returns %08x\n", r );
3518
3519     V_VT(&var) = VT_R4;
3520     V_R4(&var) = NODE_ELEMENT;
3521     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3522     ok( r == S_OK, "returns %08x\n", r );
3523     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3524
3525     V_VT(&var) = VT_BSTR;
3526     V_BSTR(&var) = SysAllocString( szOne );
3527     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3528     ok( r == S_OK, "returns %08x\n", r );
3529     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3530     VariantClear(&var);
3531
3532     V_VT(&var) = VT_BSTR;
3533     V_BSTR(&var) = SysAllocString( szOneGarbage );
3534     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3535     ok( r == E_INVALIDARG, "returns %08x\n", r );
3536     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3537     VariantClear(&var);
3538
3539     V_VT(&var) = VT_I4;
3540     V_I4(&var) = NODE_ELEMENT;
3541     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3542     ok( r == S_OK, "returns %08x\n", r );
3543
3544     EXPECT_REF(doc, 1);
3545     r = IXMLDOMDocument_appendChild( doc, node, &root );
3546     ok( r == S_OK, "returns %08x\n", r );
3547     ok( node == root, "%p %p\n", node, root );
3548     EXPECT_REF(doc, 1);
3549
3550     EXPECT_REF(node, 2);
3551
3552     ref = IXMLDOMNode_Release( node );
3553     ok(ref == 1, "ref %d\n", ref);
3554     SysFreeString( str );
3555
3556     V_VT(&var) = VT_I4;
3557     V_I4(&var) = NODE_ELEMENT;
3558     str = SysAllocString( szbs );
3559     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3560     ok( r == S_OK, "returns %08x\n", r );
3561     SysFreeString( str );
3562
3563     EXPECT_REF(node, 1);
3564
3565     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3566     ok( r == S_OK, "returns %08x\n", r );
3567
3568     EXPECT_REF(unk, 2);
3569
3570     V_VT(&var) = VT_EMPTY;
3571     child = NULL;
3572     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3573     ok( r == S_OK, "returns %08x\n", r );
3574     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3575
3576     todo_wine EXPECT_REF(unk, 4);
3577
3578     IXMLDOMNode_Release( child );
3579     IUnknown_Release( unk );
3580
3581     V_VT(&var) = VT_NULL;
3582     V_DISPATCH(&var) = (IDispatch*)node;
3583     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3584     ok( r == S_OK, "returns %08x\n", r );
3585     ok( node == child, "%p %p\n", node, child );
3586     IXMLDOMNode_Release( child );
3587
3588     V_VT(&var) = VT_NULL;
3589     V_DISPATCH(&var) = (IDispatch*)node;
3590     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3591     ok( r == S_OK, "returns %08x\n", r );
3592     IXMLDOMNode_Release( node );
3593
3594     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3595     ok( r == S_OK, "returns %08x\n", r );
3596
3597     r = IXMLDOMElement_get_attributes( element, &attr_map );
3598     ok( r == S_OK, "returns %08x\n", r );
3599     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3600     ok( r == S_OK, "returns %08x\n", r );
3601     ok( num == 0, "num %d\n", num );
3602     IXMLDOMNamedNodeMap_Release( attr_map );
3603
3604     V_VT(&var) = VT_BSTR;
3605     V_BSTR(&var) = SysAllocString( szstr1 );
3606     name = SysAllocString( szdl );
3607     r = IXMLDOMElement_setAttribute( element, name, var );
3608     ok( r == S_OK, "returns %08x\n", r );
3609     r = IXMLDOMElement_get_attributes( element, &attr_map );
3610     ok( r == S_OK, "returns %08x\n", r );
3611     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3612     ok( r == S_OK, "returns %08x\n", r );
3613     ok( num == 1, "num %d\n", num );
3614     IXMLDOMNamedNodeMap_Release( attr_map );
3615     VariantClear(&var);
3616
3617     V_VT(&var) = VT_BSTR;
3618     V_BSTR(&var) = SysAllocString( szstr2 );
3619     r = IXMLDOMElement_setAttribute( element, name, var );
3620     ok( r == S_OK, "returns %08x\n", r );
3621     r = IXMLDOMElement_get_attributes( element, &attr_map );
3622     ok( r == S_OK, "returns %08x\n", r );
3623     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3624     ok( r == S_OK, "returns %08x\n", r );
3625     ok( num == 1, "num %d\n", num );
3626     IXMLDOMNamedNodeMap_Release( attr_map );
3627     VariantClear(&var);
3628     r = IXMLDOMElement_getAttribute( element, name, &var );
3629     ok( r == S_OK, "returns %08x\n", r );
3630     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3631     VariantClear(&var);
3632     SysFreeString(name);
3633
3634     V_VT(&var) = VT_BSTR;
3635     V_BSTR(&var) = SysAllocString( szstr1 );
3636     name = SysAllocString( szlc );
3637     r = IXMLDOMElement_setAttribute( element, name, var );
3638     ok( r == S_OK, "returns %08x\n", r );
3639     r = IXMLDOMElement_get_attributes( element, &attr_map );
3640     ok( r == S_OK, "returns %08x\n", r );
3641     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3642     ok( r == S_OK, "returns %08x\n", r );
3643     ok( num == 2, "num %d\n", num );
3644     IXMLDOMNamedNodeMap_Release( attr_map );
3645     VariantClear(&var);
3646     SysFreeString(name);
3647
3648     V_VT(&var) = VT_I4;
3649     V_I4(&var) = 10;
3650     name = SysAllocString( szbs );
3651     r = IXMLDOMElement_setAttribute( element, name, var );
3652     ok( r == S_OK, "returns %08x\n", r );
3653     VariantClear(&var);
3654     r = IXMLDOMElement_getAttribute( element, name, &var );
3655     ok( r == S_OK, "returns %08x\n", r );
3656     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3657     VariantClear(&var);
3658     SysFreeString(name);
3659
3660     /* Create an Attribute */
3661     V_VT(&var) = VT_I4;
3662     V_I4(&var) = NODE_ATTRIBUTE;
3663     str = SysAllocString( szAttribute );
3664     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3665     ok( r == S_OK, "returns %08x\n", r );
3666     ok( node != NULL, "node was null\n");
3667     SysFreeString(str);
3668
3669     IXMLDOMElement_Release( element );
3670     IXMLDOMNode_Release( root );
3671     IXMLDOMDocument_Release( doc );
3672 }
3673
3674 static void test_getElementsByTagName(void)
3675 {
3676     IXMLDOMNodeList *node_list;
3677     IXMLDOMDocument *doc;
3678     IXMLDOMElement *elem;
3679     WCHAR buff[100];
3680     VARIANT_BOOL b;
3681     HRESULT r;
3682     LONG len;
3683     BSTR str;
3684
3685     doc = create_document(&IID_IXMLDOMDocument);
3686     if (!doc) return;
3687
3688     str = SysAllocString( szComplete4 );
3689     r = IXMLDOMDocument_loadXML( doc, str, &b );
3690     ok( r == S_OK, "loadXML failed\n");
3691     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3692     SysFreeString( str );
3693
3694     str = SysAllocString( szstar );
3695
3696     /* null arguments cases */
3697     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3698     ok( r == E_INVALIDARG, "ret %08x\n", r );
3699     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3700     ok( r == E_INVALIDARG, "ret %08x\n", r );
3701
3702     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3703     ok( r == S_OK, "ret %08x\n", r );
3704     r = IXMLDOMNodeList_get_length( node_list, &len );
3705     ok( r == S_OK, "ret %08x\n", r );
3706     ok( len == 6, "len %d\n", len );
3707
3708     IXMLDOMNodeList_Release( node_list );
3709     SysFreeString( str );
3710
3711     /* broken query BSTR */
3712     memcpy(&buff[2], szstar, sizeof(szstar));
3713     /* just a big length */
3714     *(DWORD*)buff = 0xf0f0;
3715     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3716     ok( r == S_OK, "ret %08x\n", r );
3717     r = IXMLDOMNodeList_get_length( node_list, &len );
3718     ok( r == S_OK, "ret %08x\n", r );
3719     ok( len == 6, "len %d\n", len );
3720     IXMLDOMNodeList_Release( node_list );
3721
3722     str = SysAllocString( szbs );
3723     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3724     ok( r == S_OK, "ret %08x\n", r );
3725     r = IXMLDOMNodeList_get_length( node_list, &len );
3726     ok( r == S_OK, "ret %08x\n", r );
3727     ok( len == 1, "len %d\n", len );
3728     IXMLDOMNodeList_Release( node_list );
3729     SysFreeString( str );
3730
3731     str = SysAllocString( szdl );
3732     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3733     ok( r == S_OK, "ret %08x\n", r );
3734     r = IXMLDOMNodeList_get_length( node_list, &len );
3735     ok( r == S_OK, "ret %08x\n", r );
3736     ok( len == 0, "len %d\n", len );
3737     IXMLDOMNodeList_Release( node_list );
3738     SysFreeString( str );
3739
3740     str = SysAllocString( szstr1 );
3741     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3742     ok( r == S_OK, "ret %08x\n", r );
3743     r = IXMLDOMNodeList_get_length( node_list, &len );
3744     ok( r == S_OK, "ret %08x\n", r );
3745     ok( len == 0, "len %d\n", len );
3746     IXMLDOMNodeList_Release( node_list );
3747     SysFreeString( str );
3748
3749     /* test for element */
3750     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3751     ok( r == S_OK, "ret %08x\n", r );
3752
3753     str = SysAllocString( szstar );
3754
3755     /* null arguments cases */
3756     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3757     ok( r == E_INVALIDARG, "ret %08x\n", r );
3758     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3759     ok( r == E_INVALIDARG, "ret %08x\n", r );
3760
3761     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3762     ok( r == S_OK, "ret %08x\n", r );
3763     r = IXMLDOMNodeList_get_length( node_list, &len );
3764     ok( r == S_OK, "ret %08x\n", r );
3765     ok( len == 5, "len %d\n", len );
3766     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3767     SysFreeString( str );
3768
3769     /* broken query BSTR */
3770     memcpy(&buff[2], szstar, sizeof(szstar));
3771     /* just a big length */
3772     *(DWORD*)buff = 0xf0f0;
3773     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3774     ok( r == S_OK, "ret %08x\n", r );
3775     r = IXMLDOMNodeList_get_length( node_list, &len );
3776     ok( r == S_OK, "ret %08x\n", r );
3777     ok( len == 5, "len %d\n", len );
3778     IXMLDOMNodeList_Release( node_list );
3779
3780     IXMLDOMElement_Release(elem);
3781
3782     IXMLDOMDocument_Release( doc );
3783 }
3784
3785 static void test_get_text(void)
3786 {
3787     HRESULT r;
3788     BSTR str;
3789     VARIANT_BOOL b;
3790     IXMLDOMDocument *doc;
3791     IXMLDOMNode *node, *node2, *node3;
3792     IXMLDOMNode *nodeRoot;
3793     IXMLDOMNodeList *node_list;
3794     IXMLDOMNamedNodeMap *node_map;
3795     LONG len;
3796
3797     doc = create_document(&IID_IXMLDOMDocument);
3798     if (!doc) return;
3799
3800     str = SysAllocString( szComplete4 );
3801     r = IXMLDOMDocument_loadXML( doc, str, &b );
3802     ok( r == S_OK, "loadXML failed\n");
3803     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3804     SysFreeString( str );
3805
3806     str = SysAllocString( szbs );
3807     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3808     ok( r == S_OK, "ret %08x\n", r );
3809     SysFreeString(str);
3810
3811     /* Test to get all child node text. */
3812     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3813     ok( r == S_OK, "ret %08x\n", r );
3814     if(r == S_OK)
3815     {
3816         r = IXMLDOMNode_get_text( nodeRoot, &str );
3817         ok( r == S_OK, "ret %08x\n", r );
3818         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
3819         SysFreeString(str);
3820
3821         IXMLDOMNode_Release(nodeRoot);
3822     }
3823
3824     r = IXMLDOMNodeList_get_length( node_list, NULL );
3825     ok( r == E_INVALIDARG, "ret %08x\n", r );
3826
3827     r = IXMLDOMNodeList_get_length( node_list, &len );
3828     ok( r == S_OK, "ret %08x\n", r );
3829     ok( len == 1, "expect 1 got %d\n", len );
3830
3831     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3832     ok( r == E_INVALIDARG, "ret %08x\n", r );
3833
3834     r = IXMLDOMNodeList_nextNode( node_list, NULL );
3835     ok( r == E_INVALIDARG, "ret %08x\n", r );
3836
3837     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
3838     ok( r == S_OK, "ret %08x\n", r );
3839     IXMLDOMNodeList_Release( node_list );
3840
3841     /* Invalid output parameter*/
3842     r = IXMLDOMNode_get_text( node, NULL );
3843     ok( r == E_INVALIDARG, "ret %08x\n", r );
3844
3845     r = IXMLDOMNode_get_text( node, &str );
3846     ok( r == S_OK, "ret %08x\n", r );
3847     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
3848     SysFreeString(str);
3849
3850     r = IXMLDOMNode_get_attributes( node, &node_map );
3851     ok( r == S_OK, "ret %08x\n", r );
3852
3853     str = SysAllocString( szvr );
3854     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3855     ok( r == S_OK, "ret %08x\n", r );
3856     SysFreeString(str);
3857
3858     r = IXMLDOMNode_get_text( node2, &str );
3859     ok( r == S_OK, "ret %08x\n", r );
3860     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3861     SysFreeString(str);
3862
3863     r = IXMLDOMNode_get_firstChild( node2, &node3 );
3864     ok( r == S_OK, "ret %08x\n", r );
3865
3866     r = IXMLDOMNode_get_text( node3, &str );
3867     ok( r == S_OK, "ret %08x\n", r );
3868     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3869     SysFreeString(str);
3870
3871
3872     IXMLDOMNode_Release( node3 );
3873     IXMLDOMNode_Release( node2 );
3874     IXMLDOMNamedNodeMap_Release( node_map );
3875     IXMLDOMNode_Release( node );
3876     IXMLDOMDocument_Release( doc );
3877 }
3878
3879 static void test_get_childNodes(void)
3880 {
3881     BSTR str;
3882     VARIANT_BOOL b;
3883     IXMLDOMDocument *doc;
3884     IXMLDOMElement *element;
3885     IXMLDOMNode *node, *node2;
3886     IXMLDOMNodeList *node_list, *node_list2;
3887     HRESULT hr;
3888     LONG len;
3889
3890     doc = create_document(&IID_IXMLDOMDocument);
3891     if (!doc) return;
3892
3893     str = SysAllocString( szComplete4 );
3894     hr = IXMLDOMDocument_loadXML( doc, str, &b );
3895     EXPECT_HR(hr, S_OK);
3896     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3897     SysFreeString( str );
3898
3899     hr = IXMLDOMDocument_get_documentElement( doc, &element );
3900     EXPECT_HR(hr, S_OK);
3901
3902     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3903     EXPECT_HR(hr, S_OK);
3904
3905     hr = IXMLDOMNodeList_get_length( node_list, &len );
3906     EXPECT_HR(hr, S_OK);
3907     ok( len == 4, "len %d\n", len);
3908
3909     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3910     EXPECT_HR(hr, S_OK);
3911
3912     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3913     EXPECT_HR(hr, S_OK);
3914
3915     hr = IXMLDOMNodeList_get_length( node_list2, &len );
3916     EXPECT_HR(hr, S_OK);
3917     ok( len == 0, "len %d\n", len);
3918
3919     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3920     EXPECT_HR(hr, S_FALSE);
3921
3922     IXMLDOMNodeList_Release( node_list2 );
3923     IXMLDOMNode_Release( node );
3924     IXMLDOMNodeList_Release( node_list );
3925     IXMLDOMElement_Release( element );
3926
3927     /* test for children of <?xml ..?> node */
3928     hr = IXMLDOMDocument_get_firstChild(doc, &node);
3929     EXPECT_HR(hr, S_OK);
3930
3931     str = NULL;
3932     hr = IXMLDOMNode_get_nodeName(node, &str);
3933     EXPECT_HR(hr, S_OK);
3934     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
3935     SysFreeString(str);
3936
3937     /* it returns empty but valid node list */
3938     node_list = (void*)0xdeadbeef;
3939     hr = IXMLDOMNode_get_childNodes(node, &node_list);
3940     EXPECT_HR(hr, S_OK);
3941
3942     len = -1;
3943     hr = IXMLDOMNodeList_get_length(node_list, &len);
3944     EXPECT_HR(hr, S_OK);
3945     ok(len == 0, "got %d\n", len);
3946
3947     IXMLDOMNodeList_Release( node_list );
3948     IXMLDOMNode_Release(node);
3949
3950     IXMLDOMDocument_Release( doc );
3951     free_bstrs();
3952 }
3953
3954 static void test_get_firstChild(void)
3955 {
3956     static WCHAR xmlW[] = {'x','m','l',0};
3957     IXMLDOMDocument *doc;
3958     IXMLDOMNode *node;
3959     VARIANT_BOOL b;
3960     HRESULT r;
3961     BSTR str;
3962
3963     doc = create_document(&IID_IXMLDOMDocument);
3964     if (!doc) return;
3965
3966     str = SysAllocString( szComplete4 );
3967     r = IXMLDOMDocument_loadXML( doc, str, &b );
3968     ok( r == S_OK, "loadXML failed\n");
3969     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3970     SysFreeString( str );
3971
3972     r = IXMLDOMDocument_get_firstChild( doc, &node );
3973     ok( r == S_OK, "ret %08x\n", r);
3974
3975     r = IXMLDOMNode_get_nodeName( node, &str );
3976     ok( r == S_OK, "ret %08x\n", r);
3977
3978     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3979
3980     SysFreeString(str);
3981     IXMLDOMNode_Release( node );
3982     IXMLDOMDocument_Release( doc );
3983 }
3984
3985 static void test_get_lastChild(void)
3986 {
3987     static WCHAR lcW[] = {'l','c',0};
3988     static WCHAR foW[] = {'f','o',0};
3989     IXMLDOMDocument *doc;
3990     IXMLDOMNode *node, *child;
3991     VARIANT_BOOL b;
3992     HRESULT r;
3993     BSTR str;
3994
3995     doc = create_document(&IID_IXMLDOMDocument);
3996     if (!doc) return;
3997
3998     str = SysAllocString( szComplete4 );
3999     r = IXMLDOMDocument_loadXML( doc, str, &b );
4000     ok( r == S_OK, "loadXML failed\n");
4001     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4002     SysFreeString( str );
4003
4004     r = IXMLDOMDocument_get_lastChild( doc, &node );
4005     ok( r == S_OK, "ret %08x\n", r);
4006
4007     r = IXMLDOMNode_get_nodeName( node, &str );
4008     ok( r == S_OK, "ret %08x\n", r);
4009
4010     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4011     SysFreeString(str);
4012
4013     r = IXMLDOMNode_get_lastChild( node, &child );
4014     ok( r == S_OK, "ret %08x\n", r);
4015
4016     r = IXMLDOMNode_get_nodeName( child, &str );
4017     ok( r == S_OK, "ret %08x\n", r);
4018
4019     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4020     SysFreeString(str);
4021
4022     IXMLDOMNode_Release( child );
4023     IXMLDOMNode_Release( node );
4024     IXMLDOMDocument_Release( doc );
4025 }
4026
4027 static void test_removeChild(void)
4028 {
4029     HRESULT r;
4030     BSTR str;
4031     VARIANT_BOOL b;
4032     IXMLDOMDocument *doc;
4033     IXMLDOMElement *element, *lc_element;
4034     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4035     IXMLDOMNodeList *root_list, *fo_list;
4036
4037     doc = create_document(&IID_IXMLDOMDocument);
4038     if (!doc) return;
4039
4040     str = SysAllocString( szComplete4 );
4041     r = IXMLDOMDocument_loadXML( doc, str, &b );
4042     ok( r == S_OK, "loadXML failed\n");
4043     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4044     SysFreeString( str );
4045
4046     r = IXMLDOMDocument_get_documentElement( doc, &element );
4047     ok( r == S_OK, "ret %08x\n", r);
4048     todo_wine EXPECT_REF(element, 2);
4049
4050     r = IXMLDOMElement_get_childNodes( element, &root_list );
4051     ok( r == S_OK, "ret %08x\n", r);
4052     EXPECT_REF(root_list, 1);
4053
4054     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4055     ok( r == S_OK, "ret %08x\n", r);
4056     EXPECT_REF(fo_node, 1);
4057
4058     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4059     ok( r == S_OK, "ret %08x\n", r);
4060     EXPECT_REF(fo_list, 1);
4061
4062     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4063     ok( r == S_OK, "ret %08x\n", r);
4064     EXPECT_REF(ba_node, 1);
4065
4066     /* invalid parameter: NULL ptr */
4067     removed_node = (void*)0xdeadbeef;
4068     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4069     ok( r == E_INVALIDARG, "ret %08x\n", r );
4070     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4071
4072     /* ba_node is a descendant of element, but not a direct child. */
4073     removed_node = (void*)0xdeadbeef;
4074     EXPECT_REF(ba_node, 1);
4075     EXPECT_CHILDREN(fo_node);
4076     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4077     ok( r == E_INVALIDARG, "ret %08x\n", r );
4078     ok( removed_node == NULL, "%p\n", removed_node );
4079     EXPECT_REF(ba_node, 1);
4080     EXPECT_CHILDREN(fo_node);
4081
4082     EXPECT_REF(ba_node, 1);
4083     EXPECT_REF(fo_node, 1);
4084     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4085     ok( r == S_OK, "ret %08x\n", r);
4086     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4087     EXPECT_REF(fo_node, 2);
4088     EXPECT_REF(ba_node, 1);
4089
4090     /* try removing already removed child */
4091     temp_node = (void*)0xdeadbeef;
4092     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4093     ok( r == E_INVALIDARG, "ret %08x\n", r);
4094     ok( temp_node == NULL, "%p\n", temp_node );
4095     IXMLDOMNode_Release( fo_node );
4096
4097     /* the removed node has no parent anymore */
4098     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4099     ok( r == S_FALSE, "ret %08x\n", r);
4100     ok( temp_node == NULL, "%p\n", temp_node );
4101
4102     IXMLDOMNode_Release( removed_node );
4103     IXMLDOMNode_Release( ba_node );
4104     IXMLDOMNodeList_Release( fo_list );
4105
4106     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4107     ok( r == S_OK, "ret %08x\n", r);
4108
4109     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4110     ok( r == S_OK, "ret %08x\n", r);
4111
4112     /* MS quirk: passing wrong interface pointer works, too */
4113     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4114     ok( r == S_OK, "ret %08x\n", r);
4115     IXMLDOMElement_Release( lc_element );
4116
4117     temp_node = (void*)0xdeadbeef;
4118     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4119     ok( r == S_FALSE, "ret %08x\n", r);
4120     ok( temp_node == NULL, "%p\n", temp_node );
4121
4122     IXMLDOMNode_Release( lc_node );
4123     IXMLDOMNodeList_Release( root_list );
4124     IXMLDOMElement_Release( element );
4125     IXMLDOMDocument_Release( doc );
4126 }
4127
4128 static void test_replaceChild(void)
4129 {
4130     HRESULT r;
4131     BSTR str;
4132     VARIANT_BOOL b;
4133     IXMLDOMDocument *doc;
4134     IXMLDOMElement *element, *ba_element;
4135     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4136     IXMLDOMNodeList *root_list, *fo_list;
4137     IUnknown * unk1, *unk2;
4138     LONG len;
4139
4140     doc = create_document(&IID_IXMLDOMDocument);
4141     if (!doc) return;
4142
4143     str = SysAllocString( szComplete4 );
4144     r = IXMLDOMDocument_loadXML( doc, str, &b );
4145     ok( r == S_OK, "loadXML failed\n");
4146     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4147     SysFreeString( str );
4148
4149     r = IXMLDOMDocument_get_documentElement( doc, &element );
4150     ok( r == S_OK, "ret %08x\n", r);
4151
4152     r = IXMLDOMElement_get_childNodes( element, &root_list );
4153     ok( r == S_OK, "ret %08x\n", r);
4154
4155     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4156     ok( r == S_OK, "ret %08x\n", r);
4157
4158     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4159     ok( r == S_OK, "ret %08x\n", r);
4160
4161     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4162     ok( r == S_OK, "ret %08x\n", r);
4163
4164     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4165     ok( r == S_OK, "ret %08x\n", r);
4166
4167     IXMLDOMNodeList_Release( fo_list );
4168
4169     /* invalid parameter: NULL ptr for element to remove */
4170     removed_node = (void*)0xdeadbeef;
4171     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4172     ok( r == E_INVALIDARG, "ret %08x\n", r );
4173     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4174
4175     /* invalid parameter: NULL for replacement element. (Sic!) */
4176     removed_node = (void*)0xdeadbeef;
4177     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4178     ok( r == E_INVALIDARG, "ret %08x\n", r );
4179     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4180
4181     /* invalid parameter: OldNode is not a child */
4182     removed_node = (void*)0xdeadbeef;
4183     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4184     ok( r == E_INVALIDARG, "ret %08x\n", r );
4185     ok( removed_node == NULL, "%p\n", removed_node );
4186     IXMLDOMNode_Release( lc_node );
4187
4188     /* invalid parameter: would create loop */
4189     removed_node = (void*)0xdeadbeef;
4190     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4191     ok( r == E_FAIL, "ret %08x\n", r );
4192     ok( removed_node == NULL, "%p\n", removed_node );
4193
4194     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4195     ok( r == S_OK, "ret %08x\n", r );
4196
4197     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4198     ok( r == S_OK, "ret %08x\n", r );
4199
4200     /* ba_node and temp_node refer to the same node, yet they
4201        are different interface pointers */
4202     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4203     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4204     ok( r == S_OK, "ret %08x\n", r );
4205     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4206     ok( r == S_OK, "ret %08x\n", r );
4207     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4208
4209     IUnknown_Release( unk1 );
4210     IUnknown_Release( unk2 );
4211
4212     /* ba_node should have been removed from below fo_node */
4213     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4214     ok( r == S_OK, "ret %08x\n", r );
4215
4216     /* MS quirk: replaceChild also accepts elements instead of nodes */
4217     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4218     ok( r == S_OK, "ret %08x\n", r );
4219     EXPECT_REF(ba_element, 2);
4220
4221     removed_node = NULL;
4222     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4223     ok( r == S_OK, "ret %08x\n", r );
4224     ok( removed_node != NULL, "got %p\n", removed_node);
4225     EXPECT_REF(ba_element, 3);
4226     IXMLDOMElement_Release( ba_element );
4227
4228     r = IXMLDOMNodeList_get_length( fo_list, &len);
4229     ok( r == S_OK, "ret %08x\n", r );
4230     ok( len == 0, "len %d\n", len);
4231
4232     IXMLDOMNodeList_Release( fo_list );
4233
4234     IXMLDOMNode_Release(ba_node);
4235     IXMLDOMNode_Release(fo_node);
4236     IXMLDOMNode_Release(temp_node);
4237     IXMLDOMNodeList_Release( root_list );
4238     IXMLDOMElement_Release( element );
4239     IXMLDOMDocument_Release( doc );
4240 }
4241
4242 static void test_removeNamedItem(void)
4243 {
4244     IXMLDOMDocument *doc;
4245     IXMLDOMElement *element;
4246     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4247     IXMLDOMNodeList *root_list;
4248     IXMLDOMNamedNodeMap * pr_attrs;
4249     VARIANT_BOOL b;
4250     BSTR str;
4251     LONG len;
4252     HRESULT r;
4253
4254     doc = create_document(&IID_IXMLDOMDocument);
4255     if (!doc) return;
4256
4257     str = SysAllocString( szComplete4 );
4258     r = IXMLDOMDocument_loadXML( doc, str, &b );
4259     ok( r == S_OK, "loadXML failed\n");
4260     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4261     SysFreeString( str );
4262
4263     r = IXMLDOMDocument_get_documentElement( doc, &element );
4264     ok( r == S_OK, "ret %08x\n", r);
4265
4266     r = IXMLDOMElement_get_childNodes( element, &root_list );
4267     ok( r == S_OK, "ret %08x\n", r);
4268
4269     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4270     ok( r == S_OK, "ret %08x\n", r);
4271
4272     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4273     ok( r == S_OK, "ret %08x\n", r);
4274
4275     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4276     ok( r == S_OK, "ret %08x\n", r);
4277     ok( len == 3, "length %d\n", len);
4278
4279     removed_node = (void*)0xdeadbeef;
4280     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4281     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4282     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4283
4284     removed_node = (void*)0xdeadbeef;
4285     str = SysAllocString(szvr);
4286     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4287     ok ( r == S_OK, "ret %08x\n", r);
4288
4289     removed_node2 = (void*)0xdeadbeef;
4290     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4291     ok ( r == S_FALSE, "ret %08x\n", r);
4292     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4293
4294     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4295     ok( r == S_OK, "ret %08x\n", r);
4296     ok( len == 2, "length %d\n", len);
4297
4298     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4299     ok ( r == S_OK, "ret %08x\n", r);
4300     IXMLDOMNode_Release(removed_node);
4301
4302     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4303     ok( r == S_OK, "ret %08x\n", r);
4304     ok( len == 3, "length %d\n", len);
4305
4306     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4307     ok ( r == S_OK, "ret %08x\n", r);
4308
4309     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4310     ok( r == S_OK, "ret %08x\n", r);
4311     ok( len == 2, "length %d\n", len);
4312
4313     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4314     ok ( r == S_FALSE, "ret %08x\n", r);
4315
4316     SysFreeString(str);
4317
4318     IXMLDOMNamedNodeMap_Release( pr_attrs );
4319     IXMLDOMNode_Release( pr_node );
4320     IXMLDOMNodeList_Release( root_list );
4321     IXMLDOMElement_Release( element );
4322     IXMLDOMDocument_Release( doc );
4323 }
4324
4325 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4326 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4327                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4328                                     DWORD expected2)
4329 {
4330     DWORD enabled, supported;
4331     HRESULT hr;
4332
4333     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4334     if (result == result2)
4335         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4336     else
4337         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4338            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4339
4340     supported = enabled = 0xCAFECAFE;
4341     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4342     ok(hr == S_OK, "ret %08x\n", hr );
4343     if (expected == expected2)
4344         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4345     else
4346         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4347            "Expected %08x, got %08x\n", expected2, enabled);
4348
4349     /* reset the safety options */
4350
4351     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4352             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4353             0);
4354     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4355
4356     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4357     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4358     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4359 }
4360
4361 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4362 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4363 {
4364     DWORD enabled = 0, supported = 0;
4365     HRESULT hr;
4366
4367     /* get */
4368     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4369     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4370     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4371     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4372
4373     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4374     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4375     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4376        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4377         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4378              "got %08x\n", supported);
4379     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4380
4381     /* set -- individual flags */
4382
4383     test_IObjectSafety_set(safety, S_OK, S_OK,
4384         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4385         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4386
4387     test_IObjectSafety_set(safety, S_OK, S_OK,
4388         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4389         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4390
4391     test_IObjectSafety_set(safety, S_OK, S_OK,
4392         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4393         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4394
4395     /* set INTERFACE_USES_DISPEX  */
4396
4397     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4398         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4399         0, 0);
4400
4401     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4402         INTERFACE_USES_DISPEX, 0,
4403         0, 0);
4404
4405     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4406         0, INTERFACE_USES_DISPEX,
4407         0, 0);
4408
4409     /* set option masking */
4410
4411     test_IObjectSafety_set(safety, S_OK, S_OK,
4412         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4413         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4414         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4415         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4416
4417     test_IObjectSafety_set(safety, S_OK, S_OK,
4418         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4419         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4420         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4421         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4422
4423     test_IObjectSafety_set(safety, S_OK, S_OK,
4424         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4425         INTERFACE_USES_SECURITY_MANAGER,
4426         0,
4427         0);
4428
4429     /* set -- inheriting previous settings */
4430
4431     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4432                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4433                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4434     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4435     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4436     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4437     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4438     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4439        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4440         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4441              "got %08x\n", supported);
4442
4443     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4444                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4445                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4446     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4447     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4448     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4449     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4450                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4451                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4452     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4453        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4454         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4455              "got %08x\n", supported);
4456 }
4457
4458 static void test_XMLHTTP(void)
4459 {
4460     static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
4461     static const WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
4462         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4463         'p','o','s','t','t','e','s','t','.','p','h','p',0};
4464     static const WCHAR xmltestW[] = {'h','t','t','p',':','/','/',
4465         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4466         'x','m','l','t','e','s','t','.','x','m','l',0};
4467     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4468     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4469
4470     IXMLHttpRequest *xhr;
4471     IObjectSafety *safety;
4472     IObjectWithSite *obj_site, *obj_site2;
4473     BSTR bstrResponse, url;
4474     VARIANT dummy;
4475     VARIANT async;
4476     VARIANT varbody;
4477     LONG state, status, bound;
4478     IDispatch *event;
4479     void *ptr;
4480     HRESULT hr;
4481
4482     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4483         &IID_IXMLHttpRequest, (void**)&xhr);
4484     if (FAILED(hr))
4485     {
4486         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4487         return;
4488     }
4489
4490     VariantInit(&dummy);
4491     V_VT(&dummy) = VT_ERROR;
4492     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4493     VariantInit(&async);
4494     V_VT(&async) = VT_BOOL;
4495     V_BOOL(&async) = VARIANT_FALSE;
4496     V_VT(&varbody) = VT_BSTR;
4497     V_BSTR(&varbody) = SysAllocString(wszBody);
4498
4499     url = SysAllocString(wszUrl);
4500
4501     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4502     EXPECT_HR(hr, S_OK);
4503
4504     hr = IXMLHttpRequest_abort(xhr);
4505     EXPECT_HR(hr, S_OK);
4506
4507     /* send before open */
4508     hr = IXMLHttpRequest_send(xhr, dummy);
4509     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4510
4511     /* initial status code */
4512     hr = IXMLHttpRequest_get_status(xhr, NULL);
4513     EXPECT_HR(hr, E_INVALIDARG);
4514
4515     status = 0xdeadbeef;
4516     hr = IXMLHttpRequest_get_status(xhr, &status);
4517     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4518     ok(status == 0xdeadbeef, "got %d\n", status);
4519
4520     /* invalid parameters */
4521     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4522     EXPECT_HR(hr, E_INVALIDARG);
4523
4524     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4525     EXPECT_HR(hr, E_INVALIDARG);
4526
4527     hr = IXMLHttpRequest_open(xhr, NULL, url, async, dummy, dummy);
4528     EXPECT_HR(hr, E_INVALIDARG);
4529
4530     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4531     EXPECT_HR(hr, E_INVALIDARG);
4532
4533     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4534     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4535
4536     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4537     EXPECT_HR(hr, E_INVALIDARG);
4538
4539     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4540     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4541
4542     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4543     EXPECT_HR(hr, E_INVALIDARG);
4544
4545     state = -1;
4546     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4547     EXPECT_HR(hr, S_OK);
4548     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4549
4550     event = create_dispevent();
4551
4552     EXPECT_REF(event, 1);
4553     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4554     EXPECT_HR(hr, S_OK);
4555     EXPECT_REF(event, 2);
4556
4557     g_unexpectedcall = g_expectedcall = 0;
4558
4559     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4560     EXPECT_HR(hr, S_OK);
4561
4562     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4563     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4564
4565     /* status code after ::open() */
4566     status = 0xdeadbeef;
4567     hr = IXMLHttpRequest_get_status(xhr, &status);
4568     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4569     ok(status == 0xdeadbeef, "got %d\n", status);
4570
4571     state = -1;
4572     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4573     EXPECT_HR(hr, S_OK);
4574     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4575
4576     hr = IXMLHttpRequest_abort(xhr);
4577     EXPECT_HR(hr, S_OK);
4578
4579     state = -1;
4580     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4581     EXPECT_HR(hr, S_OK);
4582     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4583         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4584
4585     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4586     EXPECT_HR(hr, S_OK);
4587
4588     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4589     EXPECT_HR(hr, S_OK);
4590
4591     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4592     EXPECT_HR(hr, E_INVALIDARG);
4593
4594     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4595     EXPECT_HR(hr, E_INVALIDARG);
4596
4597     SysFreeString(url);
4598
4599     hr = IXMLHttpRequest_send(xhr, varbody);
4600     if (hr == INET_E_RESOURCE_NOT_FOUND)
4601     {
4602         skip("No connection could be made with crossover.codeweavers.com\n");
4603         IXMLHttpRequest_Release(xhr);
4604         return;
4605     }
4606     EXPECT_HR(hr, S_OK);
4607
4608     /* status code after ::send() */
4609     status = 0xdeadbeef;
4610     hr = IXMLHttpRequest_get_status(xhr, &status);
4611     EXPECT_HR(hr, S_OK);
4612     ok(status == 200, "got %d\n", status);
4613
4614     /* another ::send() after completed request */
4615     hr = IXMLHttpRequest_send(xhr, varbody);
4616     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4617
4618     VariantClear(&varbody);
4619
4620     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4621     EXPECT_HR(hr, S_OK);
4622     /* the server currently returns "FAILED" because the Content-Type header is
4623      * not what the server expects */
4624     if(hr == S_OK)
4625     {
4626         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4627             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4628         SysFreeString(bstrResponse);
4629     }
4630
4631     /* GET request */
4632     url = SysAllocString(xmltestW);
4633
4634     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), url, async, dummy, dummy);
4635     EXPECT_HR(hr, S_OK);
4636
4637     V_VT(&varbody) = VT_EMPTY;
4638
4639     hr = IXMLHttpRequest_send(xhr, varbody);
4640     if (hr == INET_E_RESOURCE_NOT_FOUND)
4641     {
4642         skip("No connection could be made with crossover.codeweavers.com\n");
4643         IXMLHttpRequest_Release(xhr);
4644         return;
4645     }
4646     EXPECT_HR(hr, S_OK);
4647
4648     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4649     EXPECT_HR(hr, E_INVALIDARG);
4650
4651     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4652     EXPECT_HR(hr, S_OK);
4653     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4654         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4655     SysFreeString(bstrResponse);
4656
4657     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4658     EXPECT_HR(hr, E_INVALIDARG);
4659
4660     V_VT(&varbody) = VT_EMPTY;
4661     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4662     EXPECT_HR(hr, S_OK);
4663     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4664     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4665
4666     bound = -1;
4667     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4668     EXPECT_HR(hr, S_OK);
4669     ok(bound == 0, "got %d, expected zero bound\n", bound);
4670
4671     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4672     EXPECT_HR(hr, S_OK);
4673     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4674     SafeArrayUnaccessData(V_ARRAY(&varbody));
4675
4676     VariantClear(&varbody);
4677
4678     SysFreeString(url);
4679
4680     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4681     EXPECT_HR(hr, S_OK);
4682     if(hr == S_OK)
4683     {
4684         test_IObjectSafety_common(safety);
4685         IObjectSafety_Release(safety);
4686     }
4687
4688     IDispatch_Release(event);
4689
4690     /* interaction with object site */
4691     EXPECT_REF(xhr, 1);
4692     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4693     EXPECT_HR(hr, S_OK);
4694 todo_wine {
4695     EXPECT_REF(xhr, 1);
4696     EXPECT_REF(obj_site, 1);
4697 }
4698
4699     IObjectWithSite_AddRef(obj_site);
4700 todo_wine {
4701     EXPECT_REF(obj_site, 2);
4702     EXPECT_REF(xhr, 1);
4703 }
4704     IObjectWithSite_Release(obj_site);
4705
4706     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
4707     EXPECT_HR(hr, S_OK);
4708 todo_wine {
4709     EXPECT_REF(xhr, 1);
4710     EXPECT_REF(obj_site, 1);
4711     EXPECT_REF(obj_site2, 1);
4712     ok(obj_site != obj_site2, "expected new instance\n");
4713 }
4714     SET_EXPECT(site_qi_IServiceProvider);
4715     SET_EXPECT(sp_queryservice_SID_SBindHost);
4716     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4717     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
4718     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
4719     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
4720
4721     /* calls to IHTMLDocument2 */
4722     SET_EXPECT(htmldoc2_get_all);
4723     SET_EXPECT(collection_get_length);
4724     SET_EXPECT(htmldoc2_get_url);
4725
4726     SET_EXPECT(site_qi_IXMLDOMDocument);
4727     SET_EXPECT(site_qi_IOleClientSite);
4728
4729     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
4730     EXPECT_HR(hr, S_OK);
4731
4732 todo_wine{
4733     CHECK_CALLED(site_qi_IServiceProvider);
4734
4735     CHECK_CALLED(sp_queryservice_SID_SBindHost);
4736     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4737     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
4738     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
4739     /* this one isn't very reliable
4740     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
4741
4742     CHECK_CALLED(htmldoc2_get_all);
4743     CHECK_CALLED(collection_get_length);
4744     CHECK_CALLED(htmldoc2_get_url);
4745
4746     CHECK_CALLED(site_qi_IXMLDOMDocument);
4747     CHECK_CALLED(site_qi_IOleClientSite);
4748 }
4749     IObjectWithSite_Release(obj_site);
4750
4751     todo_wine EXPECT_REF(xhr, 1);
4752     IXMLHttpRequest_Release(xhr);
4753
4754     /* still works after request is released */
4755     SET_EXPECT(site_qi_IServiceProvider);
4756
4757     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
4758     EXPECT_HR(hr, S_OK);
4759     IObjectWithSite_Release(obj_site2);
4760
4761     free_bstrs();
4762 }
4763
4764 static void test_IXMLDOMDocument2(void)
4765 {
4766     static const WCHAR emptyW[] = {0};
4767     IXMLDOMDocument2 *doc2, *dtddoc2;
4768     IXMLDOMDocument *doc;
4769     IXMLDOMParseError* err;
4770     IDispatchEx *dispex;
4771     VARIANT_BOOL b;
4772     VARIANT var;
4773     HRESULT r;
4774     LONG res;
4775     BSTR str;
4776
4777     doc = create_document(&IID_IXMLDOMDocument);
4778     if (!doc) return;
4779
4780     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4781     if (!dtddoc2)
4782     {
4783         IXMLDOMDocument_Release(doc);
4784         return;
4785     }
4786
4787     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4788     ok( r == S_OK, "ret %08x\n", r );
4789     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4790
4791     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4792     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4793     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4794
4795     err = NULL;
4796     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4797     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4798     ok(err != NULL, "expected a pointer\n");
4799     if (err)
4800     {
4801         res = 0;
4802         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4803         /* XML_E_NOTWF */
4804         ok(res == E_XML_NOTWF, "got %08x\n", res);
4805         IXMLDOMParseError_Release(err);
4806     }
4807
4808     str = SysAllocString( szComplete4 );
4809     r = IXMLDOMDocument_loadXML( doc2, str, &b );
4810     ok( r == S_OK, "loadXML failed\n");
4811     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4812     SysFreeString( str );
4813
4814     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
4815     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4816
4817     err = NULL;
4818     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4819     ok(err != NULL, "expected a pointer\n");
4820     if (err)
4821     {
4822         res = 0;
4823         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4824         /* XML_E_NODTD */
4825         ok(res == E_XML_NODTD, "got %08x\n", res);
4826         IXMLDOMParseError_Release(err);
4827     }
4828
4829     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4830     ok( r == S_OK, "ret %08x\n", r );
4831     if(r == S_OK)
4832     {
4833         IDispatchEx_Release(dispex);
4834     }
4835
4836     /* we will check if the variant got cleared */
4837     IXMLDOMDocument2_AddRef(doc2);
4838     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4839
4840     V_VT(&var) = VT_UNKNOWN;
4841     V_UNKNOWN(&var) = (IUnknown *)doc2;
4842
4843     /* invalid calls */
4844     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
4845     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4846     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
4847
4848     /* valid call */
4849     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4850     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4851     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4852     V_VT(&var) = VT_R4;
4853
4854     /* the variant didn't get cleared*/
4855     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4856
4857     /* setProperty tests */
4858     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
4859     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
4860     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
4861     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4862     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4863     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4864
4865     V_VT(&var) = VT_BSTR;
4866     V_BSTR(&var) = SysAllocString(emptyW);
4867     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4868     ok(r == S_OK, "got 0x%08x\n", r);
4869     VariantClear(&var);
4870
4871     V_VT(&var) = VT_I2;
4872     V_I2(&var) = 0;
4873     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4874     ok(r == E_FAIL, "got 0x%08x\n", r);
4875
4876     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4877     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4878     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4879     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4880
4881     IXMLDOMDocument2_Release( doc2 );
4882     IXMLDOMDocument_Release( doc );
4883
4884     /* DTD validation */
4885     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
4886     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
4887     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4888     err = NULL;
4889     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
4890     ok(err != NULL, "expected pointer\n");
4891     if (err)
4892     {
4893         res = 0;
4894         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
4895         ok(res == 0, "got %08x\n", res);
4896         IXMLDOMParseError_Release(err);
4897     }
4898
4899     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
4900     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4901     err = NULL;
4902     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4903     ok(err != NULL, "expected pointer\n");
4904     if (err)
4905     {
4906         res = 0;
4907         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4908         /* XML_ELEMENT_UNDECLARED */
4909         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
4910         IXMLDOMParseError_Release(err);
4911     }
4912
4913     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
4914     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4915     err = NULL;
4916     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4917     ok(err != NULL, "expected pointer\n");
4918     if (err)
4919     {
4920         res = 0;
4921         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4922         /* XML_ELEMENT_ID_NOT_FOUND */
4923         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
4924         IXMLDOMParseError_Release(err);
4925     }
4926
4927     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
4928     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4929     err = NULL;
4930     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4931     ok(err != NULL, "expected pointer\n");
4932     if (err)
4933     {
4934         res = 0;
4935         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4936         /* XML_EMPTY_NOT_ALLOWED */
4937         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
4938         IXMLDOMParseError_Release(err);
4939     }
4940
4941     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
4942     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4943     err = NULL;
4944     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4945     ok(err != NULL, "expected pointer\n");
4946     if (err)
4947     {
4948         res = 0;
4949         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4950         /* XML_ROOT_NAME_MISMATCH */
4951         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
4952         IXMLDOMParseError_Release(err);
4953     }
4954
4955     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
4956     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4957     err = NULL;
4958     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4959     ok(err != NULL, "expected pointer\n");
4960     if (err)
4961     {
4962         res = 0;
4963         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4964         /* XML_INVALID_CONTENT */
4965         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
4966         IXMLDOMParseError_Release(err);
4967     }
4968
4969     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
4970     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4971     err = NULL;
4972     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4973     ok(err != NULL, "expected pointer\n");
4974     if (err)
4975     {
4976         res = 0;
4977         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4978         /* XML_ATTRIBUTE_NOT_DEFINED */
4979         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
4980         IXMLDOMParseError_Release(err);
4981     }
4982
4983     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
4984     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4985     err = NULL;
4986     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4987     ok(err != NULL, "expected pointer\n");
4988     if (err)
4989     {
4990         res = 0;
4991         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4992         /* XML_ATTRIBUTE_FIXED */
4993         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
4994         IXMLDOMParseError_Release(err);
4995     }
4996
4997     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
4998     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4999     err = NULL;
5000     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5001     ok(err != NULL, "expected pointer\n");
5002     if (err)
5003     {
5004         res = 0;
5005         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5006         /* XML_ATTRIBUTE_VALUE */
5007         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5008         IXMLDOMParseError_Release(err);
5009     }
5010
5011     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5012     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5013     err = NULL;
5014     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5015     ok(err != NULL, "expected pointer\n");
5016     if (err)
5017     {
5018         res = 0;
5019         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5020         /* XML_ILLEGAL_TEXT */
5021         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5022         IXMLDOMParseError_Release(err);
5023     }
5024
5025     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5026     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5027     err = NULL;
5028     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5029     ok(err != NULL, "expected pointer\n");
5030     if (err)
5031     {
5032         res = 0;
5033         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5034         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5035         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5036         IXMLDOMParseError_Release(err);
5037     }
5038
5039     IXMLDOMDocument2_Release( dtddoc2 );
5040     free_bstrs();
5041 }
5042
5043 #define helper_ole_check(expr) { \
5044     HRESULT r = expr; \
5045     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5046 }
5047
5048 #define helper_expect_list_and_release(list, expstr) { \
5049     char *str = list_to_string(list); \
5050     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5051     if (list) IXMLDOMNodeList_Release(list); \
5052 }
5053
5054 #define helper_expect_bstr_and_release(bstr, str) { \
5055     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5056        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5057     SysFreeString(bstr); \
5058 }
5059
5060 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5061 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5062 {
5063     IXMLDOMNode *node1, *node2;
5064     IXMLDOMNodeList *list;
5065     BSTR bstr;
5066
5067     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5068     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5069     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5070     helper_ole_check(IXMLDOMNodeList_reset(list));
5071     helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
5072
5073     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5074     helper_expect_list_and_release(list, "T1.E1.E4.E1.E2.D1 E2.E1.E4.E1.E2.D1 E3.E1.E4.E1.E2.D1 T4.E1.E4.E1.E2.D1 E5.E1.E4.E1.E2.D1");
5075     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5076     if (str)
5077     {
5078         helper_expect_bstr_and_release(bstr, str);
5079     }
5080     else
5081     {
5082         helper_expect_bstr_and_release(bstr, "This is a description.");
5083     }
5084     IXMLDOMNode_Release(node1);
5085
5086     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5087     helper_expect_list_and_release(list, "T1.E2.E4.E1.E2.D1 E2.E2.E4.E1.E2.D1 T3.E2.E4.E1.E2.D1 E4.E2.E4.E1.E2.D1 T5.E2.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1 T7.E2.E4.E1.E2.D1");
5088     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5089     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5090     IXMLDOMNode_Release(node2);
5091 }
5092
5093 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5094 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5095 {
5096     IXMLDOMNode *node1, *node2;
5097     IXMLDOMNodeList *list;
5098     BSTR bstr;
5099
5100     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5101     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5102     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5103     helper_ole_check(IXMLDOMNodeList_reset(list));
5104     helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
5105
5106     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5107     helper_expect_list_and_release(list, "T1.E2.E8.E2.E2.D1 E2.E2.E8.E2.E2.D1 T3.E2.E8.E2.E2.D1 E4.E2.E8.E2.E2.D1 T5.E2.E8.E2.E2.D1 E6.E2.E8.E2.E2.D1 T7.E2.E8.E2.E2.D1");
5108     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5109     if (str)
5110     {
5111         helper_expect_bstr_and_release(bstr, str);
5112     }
5113     else
5114     {
5115         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5116     }
5117     IXMLDOMNode_Release(node1);
5118
5119     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5120     helper_expect_list_and_release(list, "T1.E4.E8.E2.E2.D1 E2.E4.E8.E2.E2.D1 T3.E4.E8.E2.E2.D1 E4.E4.E8.E2.E2.D1 T5.E4.E8.E2.E2.D1 E6.E4.E8.E2.E2.D1 T7.E4.E8.E2.E2.D1");
5121     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5122     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5123     IXMLDOMNode_Release(node2);
5124 }
5125
5126 static void test_whitespace(void)
5127 {
5128     VARIANT_BOOL b;
5129     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5130
5131     doc1 = create_document(&IID_IXMLDOMDocument2);
5132     doc2 = create_document(&IID_IXMLDOMDocument2);
5133     if (!doc1 || !doc2) return;
5134
5135     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5136     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5137     ok(b == VARIANT_FALSE, "expected false\n");
5138     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5139     ok(b == VARIANT_TRUE, "expected true\n");
5140
5141     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5142     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5143     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5144     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5145
5146     /* switch to XPath */
5147     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5148     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5149
5150     check_ws_ignored(doc1, NULL);
5151     check_ws_preserved(doc2, NULL);
5152
5153     /* new instances copy the property */
5154     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5155     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5156
5157     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5158     ok(b == VARIANT_FALSE, "expected false\n");
5159     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5160     ok(b == VARIANT_TRUE, "expected true\n");
5161
5162     check_ws_ignored(doc3, NULL);
5163     check_ws_preserved(doc4, NULL);
5164
5165     /* setting after loading xml affects trimming of leading/trailing ws only */
5166     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5167     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5168
5169     /* the trailing "\n            " isn't there, because it was ws-only node */
5170     check_ws_ignored(doc1, "\n                This is a description. ");
5171     check_ws_preserved(doc2, "This is a description.");
5172
5173     /* it takes effect on reload */
5174     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5175     ok(b == VARIANT_TRUE, "expected true\n");
5176     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5177     ok(b == VARIANT_FALSE, "expected false\n");
5178
5179     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5180     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5181     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5182     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5183
5184     check_ws_preserved(doc1, NULL);
5185     check_ws_ignored(doc2, NULL);
5186
5187     /* other instances follow suit */
5188     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5189     ok(b == VARIANT_TRUE, "expected true\n");
5190     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5191     ok(b == VARIANT_FALSE, "expected false\n");
5192
5193     check_ws_preserved(doc3, NULL);
5194     check_ws_ignored(doc4, NULL);
5195
5196     IXMLDOMDocument_Release(doc1);
5197     IXMLDOMDocument_Release(doc2);
5198     IXMLDOMDocument_Release(doc3);
5199     IXMLDOMDocument_Release(doc4);
5200     free_bstrs();
5201 }
5202
5203 static void test_XPath(void)
5204 {
5205     VARIANT var;
5206     VARIANT_BOOL b;
5207     IXMLDOMDocument2 *doc;
5208     IXMLDOMDocument *doc2;
5209     IXMLDOMNode *rootNode;
5210     IXMLDOMNode *elem1Node;
5211     IXMLDOMNode *node;
5212     IXMLDOMNodeList *list;
5213     IXMLDOMElement *elem;
5214     IXMLDOMAttribute *attr;
5215     HRESULT hr;
5216     BSTR str;
5217
5218     doc = create_document(&IID_IXMLDOMDocument2);
5219     if (!doc) return;
5220
5221     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
5222     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5223
5224     /* switch to XPath */
5225     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5226
5227     /* some simple queries*/
5228     EXPECT_REF(doc, 1);
5229     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5230     EXPECT_HR(hr, S_OK);
5231     EXPECT_REF(doc, 1);
5232     EXPECT_LIST_LEN(list, 1);
5233
5234     EXPECT_REF(list, 1);
5235     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5236     EXPECT_HR(hr, S_OK);
5237     EXPECT_REF(list, 1);
5238     EXPECT_REF(rootNode, 1);
5239
5240     hr = IXMLDOMNodeList_reset(list);
5241     EXPECT_HR(hr, S_OK);
5242     expect_list_and_release(list, "E2.D1");
5243
5244     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5245     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5246
5247     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5248     expect_list_and_release(list, "E3.E2.E2.D1");
5249
5250     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5251     /* using get_item for query results advances the position */
5252     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5253     expect_node(node, "E2.E2.D1");
5254     IXMLDOMNode_Release(node);
5255     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5256     expect_node(node, "E4.E2.D1");
5257     IXMLDOMNode_Release(node);
5258     ole_check(IXMLDOMNodeList_reset(list));
5259     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5260
5261     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5262     expect_list_and_release(list, "E2.D1");
5263
5264     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5265     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5266     ole_check(IXMLDOMNodeList_reset(list));
5267     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5268
5269     /* select an attribute */
5270     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5271     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5272
5273     /* would evaluate to a number */
5274     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5275     /* would evaluate to a boolean */
5276     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5277     /* would evaluate to a string */
5278     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5279
5280     /* no results */
5281     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5282     expect_list_and_release(list, "");
5283     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5284     expect_list_and_release(list, "");
5285     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5286     expect_list_and_release(list, "");
5287     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5288     expect_list_and_release(list, "");
5289
5290     /* foo undeclared in document node */
5291     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5292     /* undeclared in <root> node */
5293     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5294     /* undeclared in <elem> node */
5295     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5296     /* but this trick can be used */
5297     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5298     expect_list_and_release(list, "E3.E4.E2.D1");
5299
5300     /* it has to be declared in SelectionNamespaces */
5301     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5302         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5303
5304     /* now the namespace can be used */
5305     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5306     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5307     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5308     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5309     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5310     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5311     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5312     expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
5313
5314     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5315     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5316         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5317
5318     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5319
5320     VariantInit(&var);
5321     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5322     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5323     if (V_VT(&var) == VT_BSTR)
5324         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5325
5326     /* extra attributes - same thing*/
5327     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5328         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5329     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5330
5331     IXMLDOMNode_Release(rootNode);
5332     IXMLDOMNode_Release(elem1Node);
5333
5334     /* alter document with already built list */
5335     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5336     EXPECT_HR(hr, S_OK);
5337     EXPECT_LIST_LEN(list, 1);
5338
5339     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5340     EXPECT_HR(hr, S_OK);
5341     EXPECT_REF(rootNode, 1);
5342     EXPECT_REF(doc, 1);
5343
5344     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5345     EXPECT_HR(hr, S_OK);
5346     IXMLDOMNode_Release(rootNode);
5347
5348     EXPECT_LIST_LEN(list, 1);
5349
5350     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5351     EXPECT_HR(hr, S_OK);
5352     EXPECT_REF(rootNode, 1);
5353
5354     IXMLDOMNodeList_Release(list);
5355
5356     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5357     EXPECT_HR(hr, S_OK);
5358     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5359     SysFreeString(str);
5360     IXMLDOMNode_Release(rootNode);
5361
5362     /* alter node from list and get it another time */
5363     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5364     EXPECT_HR(hr, S_OK);
5365     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5366
5367     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5368     EXPECT_HR(hr, S_OK);
5369     EXPECT_LIST_LEN(list, 1);
5370
5371     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5372     EXPECT_HR(hr, S_OK);
5373
5374     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5375     EXPECT_HR(hr, S_OK);
5376
5377     V_VT(&var) = VT_I2;
5378     V_I2(&var) = 1;
5379     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5380     EXPECT_HR(hr, S_OK);
5381     IXMLDOMElement_Release(elem);
5382     IXMLDOMNode_Release(rootNode);
5383
5384     /* now check attribute to be present */
5385     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5386     EXPECT_HR(hr, S_OK);
5387
5388     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5389     EXPECT_HR(hr, S_OK);
5390
5391     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5392     EXPECT_HR(hr, S_OK);
5393     IXMLDOMAttribute_Release(attr);
5394
5395     IXMLDOMElement_Release(elem);
5396     IXMLDOMNode_Release(rootNode);
5397
5398     /* and now check for attribute in original document */
5399     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5400     EXPECT_HR(hr, S_OK);
5401
5402     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5403     EXPECT_HR(hr, S_OK);
5404     IXMLDOMAttribute_Release(attr);
5405
5406     IXMLDOMElement_Release(elem);
5407
5408     /* attach node from list to another document */
5409     doc2 = create_document(&IID_IXMLDOMDocument);
5410
5411     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5412     EXPECT_HR(hr, S_OK);
5413     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5414
5415     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5416     EXPECT_HR(hr, S_OK);
5417     EXPECT_LIST_LEN(list, 1);
5418
5419     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5420     EXPECT_HR(hr, S_OK);
5421     EXPECT_REF(rootNode, 1);
5422
5423     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5424     EXPECT_HR(hr, S_OK);
5425     EXPECT_REF(rootNode, 1);
5426     EXPECT_REF(doc2, 1);
5427     EXPECT_REF(list, 1);
5428
5429     EXPECT_LIST_LEN(list, 1);
5430
5431     IXMLDOMNode_Release(rootNode);
5432     IXMLDOMNodeList_Release(list);
5433     IXMLDOMDocument_Release(doc2);
5434
5435     IXMLDOMDocument2_Release(doc);
5436     free_bstrs();
5437 }
5438
5439 static void test_cloneNode(void )
5440 {
5441     IXMLDOMDocument *doc, *doc2;
5442     VARIANT_BOOL b;
5443     IXMLDOMNodeList *pList;
5444     IXMLDOMNamedNodeMap *mapAttr;
5445     LONG length, length1;
5446     LONG attr_cnt, attr_cnt1;
5447     IXMLDOMNode *node;
5448     IXMLDOMNode *node_clone;
5449     IXMLDOMNode *node_first;
5450     HRESULT hr;
5451     BSTR str;
5452
5453     doc = create_document(&IID_IXMLDOMDocument);
5454     if (!doc) return;
5455
5456     str = SysAllocString( szComplete4 );
5457     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
5458     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5459     SysFreeString(str);
5460
5461     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5462     ok( hr == S_OK, "ret %08x\n", hr );
5463     ok( node != NULL, "node %p\n", node );
5464
5465     /* Check invalid parameter */
5466     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5467     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5468
5469     /* All Children */
5470     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5471     ok( hr == S_OK, "ret %08x\n", hr );
5472     ok( node_clone != NULL, "node %p\n", node );
5473
5474     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5475     ok( hr == S_OK, "ret %08x\n", hr );
5476     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5477     ok( hr == S_OK, "ret %08x\n", hr );
5478     IXMLDOMDocument_Release(doc2);
5479     IXMLDOMNode_Release(node_first);
5480
5481     hr = IXMLDOMNode_get_childNodes(node, &pList);
5482     ok( hr == S_OK, "ret %08x\n", hr );
5483     length = 0;
5484     hr = IXMLDOMNodeList_get_length(pList, &length);
5485     ok( hr == S_OK, "ret %08x\n", hr );
5486     ok(length == 1, "got %d\n", length);
5487     IXMLDOMNodeList_Release(pList);
5488
5489     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5490     ok( hr == S_OK, "ret %08x\n", hr );
5491     attr_cnt = 0;
5492     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5493     ok( hr == S_OK, "ret %08x\n", hr );
5494     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5495     IXMLDOMNamedNodeMap_Release(mapAttr);
5496
5497     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5498     ok( hr == S_OK, "ret %08x\n", hr );
5499     length1 = 0;
5500     hr = IXMLDOMNodeList_get_length(pList, &length1);
5501     ok(length1 == 1, "got %d\n", length1);
5502     ok( hr == S_OK, "ret %08x\n", hr );
5503     IXMLDOMNodeList_Release(pList);
5504
5505     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5506     ok( hr == S_OK, "ret %08x\n", hr );
5507     attr_cnt1 = 0;
5508     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5509     ok( hr == S_OK, "ret %08x\n", hr );
5510     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5511     IXMLDOMNamedNodeMap_Release(mapAttr);
5512
5513     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5514     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5515     IXMLDOMNode_Release(node_clone);
5516
5517     /* No Children */
5518     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5519     ok( hr == S_OK, "ret %08x\n", hr );
5520     ok( node_clone != NULL, "node %p\n", node );
5521
5522     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5523     ok(hr == S_FALSE, "ret %08x\n", hr );
5524
5525     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5526     ok(hr == S_OK, "ret %08x\n", hr );
5527     hr = IXMLDOMNodeList_get_length(pList, &length1);
5528     ok(hr == S_OK, "ret %08x\n", hr );
5529     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5530     IXMLDOMNodeList_Release(pList);
5531
5532     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5533     ok(hr == S_OK, "ret %08x\n", hr );
5534     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5535     ok(hr == S_OK, "ret %08x\n", hr );
5536     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5537     IXMLDOMNamedNodeMap_Release(mapAttr);
5538
5539     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5540     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5541     IXMLDOMNode_Release(node_clone);
5542
5543     IXMLDOMNode_Release(node);
5544     IXMLDOMDocument_Release(doc);
5545     free_bstrs();
5546 }
5547
5548 static void test_xmlTypes(void)
5549 {
5550     IXMLDOMDocument *doc;
5551     IXMLDOMElement *pRoot;
5552     HRESULT hr;
5553     IXMLDOMComment *pComment;
5554     IXMLDOMElement *pElement;
5555     IXMLDOMAttribute *pAttribute;
5556     IXMLDOMNamedNodeMap *pAttribs;
5557     IXMLDOMCDATASection *pCDataSec;
5558     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5559     IXMLDOMDocumentFragment *pDocFrag = NULL;
5560     IXMLDOMEntityReference *pEntityRef = NULL;
5561     BSTR str;
5562     IXMLDOMNode *pNextChild;
5563     VARIANT v;
5564     LONG len = 0;
5565
5566     doc = create_document(&IID_IXMLDOMDocument);
5567     if (!doc) return;
5568
5569     pNextChild = (void*)0xdeadbeef;
5570     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5571     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5572
5573     pNextChild = (void*)0xdeadbeef;
5574     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5575     ok(hr == S_FALSE, "ret %08x\n", hr );
5576     ok(pNextChild == NULL, "pDocChild not NULL\n");
5577
5578     /* test previous Sibling */
5579     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5580     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5581
5582     pNextChild = (void*)0xdeadbeef;
5583     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5584     ok(hr == S_FALSE, "ret %08x\n", hr );
5585     ok(pNextChild == NULL, "pNextChild not NULL\n");
5586
5587     /* test get_dataType */
5588     V_VT(&v) = VT_EMPTY;
5589     hr = IXMLDOMDocument_get_dataType(doc, &v);
5590     ok(hr == S_FALSE, "ret %08x\n", hr );
5591     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5592     VariantClear(&v);
5593
5594     /* test implementation */
5595     hr = IXMLDOMDocument_get_implementation(doc, NULL);
5596     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5597
5598     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5599     ok(hr == S_OK, "ret %08x\n", hr );
5600     if(hr == S_OK)
5601     {
5602         VARIANT_BOOL hasFeature = VARIANT_TRUE;
5603         BSTR sEmpty = SysAllocStringLen(NULL, 0);
5604
5605         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5606         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5607
5608         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5609         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5610
5611         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5612         ok(hr == S_OK, "ret %08x\n", hr );
5613         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5614
5615         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5616         ok(hr == S_OK, "ret %08x\n", hr );
5617         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5618
5619         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5620         ok(hr == S_OK, "ret %08x\n", hr );
5621         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5622
5623         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5624         ok(hr == S_OK, "ret %08x\n", hr );
5625         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5626
5627         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5628         ok(hr == S_OK, "ret %08x\n", hr );
5629         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5630
5631         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5632         ok(hr == S_OK, "ret %08x\n", hr );
5633         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5634
5635         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5636         ok(hr == S_OK, "ret %08x\n", hr );
5637         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5638
5639         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5640         ok(hr == S_OK, "ret %08x\n", hr );
5641         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5642
5643         SysFreeString(sEmpty);
5644         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5645     }
5646
5647     pRoot = (IXMLDOMElement*)0x1;
5648     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5649     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5650     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5651
5652     pRoot = (IXMLDOMElement*)0x1;
5653     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5654     ok(hr == E_FAIL, "ret %08x\n", hr );
5655     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5656
5657     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5658     ok(hr == S_OK, "ret %08x\n", hr );
5659     if(hr == S_OK)
5660     {
5661         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5662         ok(hr == S_OK, "ret %08x\n", hr );
5663         if(hr == S_OK)
5664         {
5665             /* Comment */
5666             str = SysAllocString(szComment);
5667             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5668             SysFreeString(str);
5669             ok(hr == S_OK, "ret %08x\n", hr );
5670             if(hr == S_OK)
5671             {
5672                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5673                 ok(hr == S_OK, "ret %08x\n", hr );
5674
5675                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5676                 ok(hr == S_OK, "ret %08x\n", hr );
5677                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
5678                 SysFreeString(str);
5679
5680                 hr = IXMLDOMComment_get_xml(pComment, &str);
5681                 ok(hr == S_OK, "ret %08x\n", hr );
5682                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
5683                 SysFreeString(str);
5684
5685                 /* put data Tests */
5686                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5687                 ok(hr == S_OK, "ret %08x\n", hr );
5688
5689                 /* get data Tests */
5690                 hr = IXMLDOMComment_get_data(pComment, &str);
5691                 ok(hr == S_OK, "ret %08x\n", hr );
5692                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
5693                 SysFreeString(str);
5694
5695                 /* get data Tests */
5696                 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
5697                 ok(hr == S_OK, "ret %08x\n", hr );
5698                 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
5699                 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
5700                 VariantClear(&v);
5701
5702                 /* Confirm XML text is good */
5703                 hr = IXMLDOMComment_get_xml(pComment, &str);
5704                 ok(hr == S_OK, "ret %08x\n", hr );
5705                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
5706                 SysFreeString(str);
5707
5708                 /* Confirm we get the put_data Text back */
5709                 hr = IXMLDOMComment_get_text(pComment, &str);
5710                 ok(hr == S_OK, "ret %08x\n", hr );
5711                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
5712                 SysFreeString(str);
5713
5714                 /* test length property */
5715                 hr = IXMLDOMComment_get_length(pComment, &len);
5716                 ok(hr == S_OK, "ret %08x\n", hr );
5717                 ok(len == 21, "expected 21 got %d\n", len);
5718
5719                 /* test substringData */
5720                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5721                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5722
5723                 /* test substringData - Invalid offset */
5724                 str = (BSTR)&szElement;
5725                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5726                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5727                 ok( str == NULL, "incorrect string\n");
5728
5729                 /* test substringData - Invalid offset */
5730                 str = (BSTR)&szElement;
5731                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5732                 ok(hr == S_FALSE, "ret %08x\n", hr );
5733                 ok( str == NULL, "incorrect string\n");
5734
5735                 /* test substringData - Invalid size */
5736                 str = (BSTR)&szElement;
5737                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5738                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5739                 ok( str == NULL, "incorrect string\n");
5740
5741                 /* test substringData - Invalid size */
5742                 str = (BSTR)&szElement;
5743                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5744                 ok(hr == S_FALSE, "ret %08x\n", hr );
5745                 ok( str == NULL, "incorrect string\n");
5746
5747                 /* test substringData - Start of string */
5748                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5749                 ok(hr == S_OK, "ret %08x\n", hr );
5750                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5751                 SysFreeString(str);
5752
5753                 /* test substringData - Middle of string */
5754                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5755                 ok(hr == S_OK, "ret %08x\n", hr );
5756                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5757                 SysFreeString(str);
5758
5759                 /* test substringData - End of string */
5760                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5761                 ok(hr == S_OK, "ret %08x\n", hr );
5762                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5763                 SysFreeString(str);
5764
5765                 /* test appendData */
5766                 hr = IXMLDOMComment_appendData(pComment, NULL);
5767                 ok(hr == S_OK, "ret %08x\n", hr );
5768
5769                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5770                 ok(hr == S_OK, "ret %08x\n", hr );
5771
5772                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5773                 ok(hr == S_OK, "ret %08x\n", hr );
5774
5775                 hr = IXMLDOMComment_get_text(pComment, &str);
5776                 ok(hr == S_OK, "ret %08x\n", hr );
5777                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5778                 SysFreeString(str);
5779
5780                 /* test insertData */
5781                 str = SysAllocStringLen(NULL, 0);
5782                 hr = IXMLDOMComment_insertData(pComment, -1, str);
5783                 ok(hr == S_OK, "ret %08x\n", hr );
5784
5785                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5786                 ok(hr == S_OK, "ret %08x\n", hr );
5787
5788                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5789                 ok(hr == S_OK, "ret %08x\n", hr );
5790
5791                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5792                 ok(hr == S_OK, "ret %08x\n", hr );
5793
5794                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5795                 ok(hr == S_OK, "ret %08x\n", hr );
5796
5797                 hr = IXMLDOMComment_insertData(pComment, 0, str);
5798                 ok(hr == S_OK, "ret %08x\n", hr );
5799                 SysFreeString(str);
5800
5801                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5802                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5803
5804                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5805                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5806
5807                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5808                 ok(hr == S_OK, "ret %08x\n", hr );
5809
5810                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5811                 ok(hr == S_OK, "ret %08x\n", hr );
5812
5813                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5814                 ok(hr == S_OK, "ret %08x\n", hr );
5815
5816                 hr = IXMLDOMComment_get_text(pComment, &str);
5817                 ok(hr == S_OK, "ret %08x\n", hr );
5818                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5819                 SysFreeString(str);
5820
5821                 /* delete data */
5822                 /* invalid arguments */
5823                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
5824                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5825
5826                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
5827                 ok(hr == S_OK, "ret %08x\n", hr );
5828
5829                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
5830                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5831
5832                 hr = IXMLDOMComment_get_length(pComment, &len);
5833                 ok(hr == S_OK, "ret %08x\n", hr );
5834                 ok(len == 43, "expected 43 got %d\n", len);
5835
5836                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
5837                 ok(hr == S_OK, "ret %08x\n", hr );
5838
5839                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
5840                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5841
5842                 /* delete from start */
5843                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
5844                 ok(hr == S_OK, "ret %08x\n", hr );
5845
5846                 hr = IXMLDOMComment_get_length(pComment, &len);
5847                 ok(hr == S_OK, "ret %08x\n", hr );
5848                 ok(len == 38, "expected 38 got %d\n", len);
5849
5850                 hr = IXMLDOMComment_get_text(pComment, &str);
5851                 ok(hr == S_OK, "ret %08x\n", hr );
5852                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5853                 SysFreeString(str);
5854
5855                 /* delete from end */
5856                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
5857                 ok(hr == S_OK, "ret %08x\n", hr );
5858
5859                 hr = IXMLDOMComment_get_length(pComment, &len);
5860                 ok(hr == S_OK, "ret %08x\n", hr );
5861                 ok(len == 35, "expected 35 got %d\n", len);
5862
5863                 hr = IXMLDOMComment_get_text(pComment, &str);
5864                 ok(hr == S_OK, "ret %08x\n", hr );
5865                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5866                 SysFreeString(str);
5867
5868                 /* delete from inside */
5869                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
5870                 ok(hr == S_OK, "ret %08x\n", hr );
5871
5872                 hr = IXMLDOMComment_get_length(pComment, &len);
5873                 ok(hr == S_OK, "ret %08x\n", hr );
5874                 ok(len == 2, "expected 2 got %d\n", len);
5875
5876                 hr = IXMLDOMComment_get_text(pComment, &str);
5877                 ok(hr == S_OK, "ret %08x\n", hr );
5878                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5879                 SysFreeString(str);
5880
5881                 /* delete whole data ... */
5882                 hr = IXMLDOMComment_get_length(pComment, &len);
5883                 ok(hr == S_OK, "ret %08x\n", hr );
5884
5885                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5886                 ok(hr == S_OK, "ret %08x\n", hr );
5887                 /* ... and try again with empty string */
5888                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5889                 ok(hr == S_OK, "ret %08x\n", hr );
5890
5891                 /* ::replaceData() */
5892                 V_VT(&v) = VT_BSTR;
5893                 V_BSTR(&v) = SysAllocString(szstr1);
5894                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
5895                 ok(hr == S_OK, "ret %08x\n", hr );
5896                 VariantClear(&v);
5897
5898                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
5899                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5900                 hr = IXMLDOMComment_get_text(pComment, &str);
5901                 ok(hr == S_OK, "ret %08x\n", hr );
5902                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5903                 SysFreeString(str);
5904
5905                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
5906                 ok(hr == S_OK, "ret %08x\n", hr );
5907                 hr = IXMLDOMComment_get_text(pComment, &str);
5908                 ok(hr == S_OK, "ret %08x\n", hr );
5909                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5910                 SysFreeString(str);
5911
5912                 /* NULL pointer means delete */
5913                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
5914                 ok(hr == S_OK, "ret %08x\n", hr );
5915                 hr = IXMLDOMComment_get_text(pComment, &str);
5916                 ok(hr == S_OK, "ret %08x\n", hr );
5917                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5918                 SysFreeString(str);
5919
5920                 /* empty string means delete */
5921                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
5922                 ok(hr == S_OK, "ret %08x\n", hr );
5923                 hr = IXMLDOMComment_get_text(pComment, &str);
5924                 ok(hr == S_OK, "ret %08x\n", hr );
5925                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5926                 SysFreeString(str);
5927
5928                 /* zero count means insert */
5929                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
5930                 ok(hr == S_OK, "ret %08x\n", hr );
5931                 hr = IXMLDOMComment_get_text(pComment, &str);
5932                 ok(hr == S_OK, "ret %08x\n", hr );
5933                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5934                 SysFreeString(str);
5935
5936                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
5937                 ok(hr == S_OK, "ret %08x\n", hr );
5938
5939                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
5940                 ok(hr == S_OK, "ret %08x\n", hr );
5941                 hr = IXMLDOMComment_get_text(pComment, &str);
5942                 ok(hr == S_OK, "ret %08x\n", hr );
5943                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5944                 SysFreeString(str);
5945
5946                 /* nonempty string, count greater than its length */
5947                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
5948                 ok(hr == S_OK, "ret %08x\n", hr );
5949                 hr = IXMLDOMComment_get_text(pComment, &str);
5950                 ok(hr == S_OK, "ret %08x\n", hr );
5951                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5952                 SysFreeString(str);
5953
5954                 /* nonempty string, count less than its length */
5955                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
5956                 ok(hr == S_OK, "ret %08x\n", hr );
5957                 hr = IXMLDOMComment_get_text(pComment, &str);
5958                 ok(hr == S_OK, "ret %08x\n", hr );
5959                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5960                 SysFreeString(str);
5961
5962                 IXMLDOMComment_Release(pComment);
5963             }
5964
5965             /* Element */
5966             str = SysAllocString(szElement);
5967             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
5968             SysFreeString(str);
5969             ok(hr == S_OK, "ret %08x\n", hr );
5970             if(hr == S_OK)
5971             {
5972                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5973                 ok(hr == S_OK, "ret %08x\n", hr );
5974
5975                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
5976                 ok(hr == S_OK, "ret %08x\n", hr );
5977                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
5978                 SysFreeString(str);
5979
5980                 hr = IXMLDOMElement_get_xml(pElement, &str);
5981                 ok(hr == S_OK, "ret %08x\n", hr );
5982                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
5983                 SysFreeString(str);
5984
5985                 /* Attribute */
5986                 pAttribute = (IXMLDOMAttribute*)0x1;
5987                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
5988                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5989                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5990
5991                 pAttribute = (IXMLDOMAttribute*)0x1;
5992                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
5993                 ok(hr == E_FAIL, "ret %08x\n", hr );
5994                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5995
5996                 str = SysAllocString(szAttribute);
5997                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
5998                 SysFreeString(str);
5999                 ok(hr == S_OK, "ret %08x\n", hr );
6000                 if(hr == S_OK)
6001                 {
6002                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6003
6004                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6005                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6006
6007                     pNextChild = (IXMLDOMNode *)0x1;
6008                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6009                     ok(hr == S_FALSE, "ret %08x\n", hr );
6010                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6011
6012                     /* test Previous Sibling*/
6013                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6014                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6015
6016                     pNextChild = (IXMLDOMNode *)0x1;
6017                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6018                     ok(hr == S_FALSE, "ret %08x\n", hr );
6019                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6020
6021                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6022                     ok(hr == E_FAIL, "ret %08x\n", hr );
6023                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6024
6025                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6026                     ok(hr == S_OK, "ret %08x\n", hr );
6027                     if ( hr == S_OK )
6028                     {
6029                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6030                         ok(hr == S_OK, "ret %08x\n", hr );
6031
6032                         IXMLDOMNamedNodeMap_Release(pAttribs);
6033                     }
6034
6035                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6036                     ok(hr == S_OK, "ret %08x\n", hr );
6037                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6038                     SysFreeString(str);
6039
6040                     /* test nodeName */
6041                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6042                     ok(hr == S_OK, "ret %08x\n", hr );
6043                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6044                     SysFreeString(str);
6045
6046                     /* test name property */
6047                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6048                     ok(hr == S_OK, "ret %08x\n", hr );
6049                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6050                     SysFreeString(str);
6051
6052                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6053                     ok(hr == S_OK, "ret %08x\n", hr );
6054                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6055                     SysFreeString(str);
6056
6057                     IXMLDOMAttribute_Release(pAttribute);
6058
6059                     /* Check Element again with the Add Attribute*/
6060                     hr = IXMLDOMElement_get_xml(pElement, &str);
6061                     ok(hr == S_OK, "ret %08x\n", hr );
6062                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6063                     SysFreeString(str);
6064                 }
6065
6066                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6067                 ok(hr == S_OK, "ret %08x\n", hr );
6068
6069                 hr = IXMLDOMElement_get_xml(pElement, &str);
6070                 ok(hr == S_OK, "ret %08x\n", hr );
6071                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6072                 SysFreeString(str);
6073
6074                 /* Test for reversible escaping */
6075                 str = SysAllocString( szStrangeChars );
6076                 hr = IXMLDOMElement_put_text(pElement, str);
6077                 ok(hr == S_OK, "ret %08x\n", hr );
6078                 SysFreeString( str );
6079
6080                 hr = IXMLDOMElement_get_xml(pElement, &str);
6081                 ok(hr == S_OK, "ret %08x\n", hr );
6082                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6083                 SysFreeString(str);
6084
6085                 hr = IXMLDOMElement_get_text(pElement, &str);
6086                 ok(hr == S_OK, "ret %08x\n", hr );
6087                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6088                 SysFreeString(str);
6089
6090                 IXMLDOMElement_Release(pElement);
6091             }
6092
6093             /* CData Section */
6094             str = SysAllocString(szCData);
6095             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6096             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6097
6098             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6099             SysFreeString(str);
6100             ok(hr == S_OK, "ret %08x\n", hr );
6101             if(hr == S_OK)
6102             {
6103                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6104                 VARIANT var;
6105
6106                 VariantInit(&var);
6107
6108                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6109                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6110
6111                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6112                 ok(hr == S_OK, "ret %08x\n", hr );
6113
6114                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6115                 ok(hr == S_OK, "ret %08x\n", hr );
6116                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6117                 SysFreeString(str);
6118
6119                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6120                 ok(hr == S_OK, "ret %08x\n", hr );
6121                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6122                 SysFreeString(str);
6123
6124                 /* test lastChild */
6125                 pNextChild = (IXMLDOMNode*)0x1;
6126                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6127                 ok(hr == S_FALSE, "ret %08x\n", hr );
6128                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6129
6130                 /* put data Tests */
6131                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6132                 ok(hr == S_OK, "ret %08x\n", hr );
6133
6134                 /* Confirm XML text is good */
6135                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6136                 ok(hr == S_OK, "ret %08x\n", hr );
6137                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6138                 SysFreeString(str);
6139
6140                 /* Confirm we get the put_data Text back */
6141                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6142                 ok(hr == S_OK, "ret %08x\n", hr );
6143                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6144                 SysFreeString(str);
6145
6146                 /* test length property */
6147                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6148                 ok(hr == S_OK, "ret %08x\n", hr );
6149                 ok(len == 21, "expected 21 got %d\n", len);
6150
6151                 /* test get nodeValue */
6152                 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
6153                 ok(hr == S_OK, "ret %08x\n", hr );
6154                 ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var));
6155                 ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6156                 VariantClear(&var);
6157
6158                 /* test get data */
6159                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6160                 ok(hr == S_OK, "ret %08x\n", hr );
6161                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6162                 SysFreeString(str);
6163
6164                 /* test substringData */
6165                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6166                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6167
6168                 /* test substringData - Invalid offset */
6169                 str = (BSTR)&szElement;
6170                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6171                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6172                 ok( str == NULL, "incorrect string\n");
6173
6174                 /* test substringData - Invalid offset */
6175                 str = (BSTR)&szElement;
6176                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6177                 ok(hr == S_FALSE, "ret %08x\n", hr );
6178                 ok( str == NULL, "incorrect string\n");
6179
6180                 /* test substringData - Invalid size */
6181                 str = (BSTR)&szElement;
6182                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6183                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6184                 ok( str == NULL, "incorrect string\n");
6185
6186                 /* test substringData - Invalid size */
6187                 str = (BSTR)&szElement;
6188                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6189                 ok(hr == S_FALSE, "ret %08x\n", hr );
6190                 ok( str == NULL, "incorrect string\n");
6191
6192                 /* test substringData - Start of string */
6193                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6194                 ok(hr == S_OK, "ret %08x\n", hr );
6195                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6196                 SysFreeString(str);
6197
6198                 /* test substringData - Middle of string */
6199                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6200                 ok(hr == S_OK, "ret %08x\n", hr );
6201                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6202                 SysFreeString(str);
6203
6204                 /* test substringData - End of string */
6205                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6206                 ok(hr == S_OK, "ret %08x\n", hr );
6207                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6208                 SysFreeString(str);
6209
6210                 /* test appendData */
6211                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6212                 ok(hr == S_OK, "ret %08x\n", hr );
6213
6214                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6215                 ok(hr == S_OK, "ret %08x\n", hr );
6216
6217                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6218                 ok(hr == S_OK, "ret %08x\n", hr );
6219
6220                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6221                 ok(hr == S_OK, "ret %08x\n", hr );
6222                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6223                 SysFreeString(str);
6224
6225                 /* test insertData */
6226                 str = SysAllocStringLen(NULL, 0);
6227                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6228                 ok(hr == S_OK, "ret %08x\n", hr );
6229
6230                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6231                 ok(hr == S_OK, "ret %08x\n", hr );
6232
6233                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6234                 ok(hr == S_OK, "ret %08x\n", hr );
6235
6236                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6237                 ok(hr == S_OK, "ret %08x\n", hr );
6238
6239                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6240                 ok(hr == S_OK, "ret %08x\n", hr );
6241
6242                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6243                 ok(hr == S_OK, "ret %08x\n", hr );
6244                 SysFreeString(str);
6245
6246                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6247                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6248
6249                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6250                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6251
6252                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6253                 ok(hr == S_OK, "ret %08x\n", hr );
6254
6255                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6256                 ok(hr == S_OK, "ret %08x\n", hr );
6257
6258                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6259                 ok(hr == S_OK, "ret %08x\n", hr );
6260
6261                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6262                 ok(hr == S_OK, "ret %08x\n", hr );
6263                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6264                 SysFreeString(str);
6265
6266                 /* delete data */
6267                 /* invalid arguments */
6268                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6269                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6270
6271                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6272                 ok(hr == S_OK, "ret %08x\n", hr );
6273
6274                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6275                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6276
6277                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6278                 ok(hr == S_OK, "ret %08x\n", hr );
6279                 ok(len == 43, "expected 43 got %d\n", len);
6280
6281                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6282                 ok(hr == S_OK, "ret %08x\n", hr );
6283
6284                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6285                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6286
6287                 /* delete from start */
6288                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6289                 ok(hr == S_OK, "ret %08x\n", hr );
6290
6291                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6292                 ok(hr == S_OK, "ret %08x\n", hr );
6293                 ok(len == 38, "expected 38 got %d\n", len);
6294
6295                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6296                 ok(hr == S_OK, "ret %08x\n", hr );
6297                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6298                 SysFreeString(str);
6299
6300                 /* delete from end */
6301                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6302                 ok(hr == S_OK, "ret %08x\n", hr );
6303
6304                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6305                 ok(hr == S_OK, "ret %08x\n", hr );
6306                 ok(len == 35, "expected 35 got %d\n", len);
6307
6308                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6309                 ok(hr == S_OK, "ret %08x\n", hr );
6310                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6311                 SysFreeString(str);
6312
6313                 /* delete from inside */
6314                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6315                 ok(hr == S_OK, "ret %08x\n", hr );
6316
6317                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6318                 ok(hr == S_OK, "ret %08x\n", hr );
6319                 ok(len == 2, "expected 2 got %d\n", len);
6320
6321                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6322                 ok(hr == S_OK, "ret %08x\n", hr );
6323                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6324                 SysFreeString(str);
6325
6326                 /* delete whole data ... */
6327                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6328                 ok(hr == S_OK, "ret %08x\n", hr );
6329
6330                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6331                 ok(hr == S_OK, "ret %08x\n", hr );
6332
6333                 /* ... and try again with empty string */
6334                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6335                 ok(hr == S_OK, "ret %08x\n", hr );
6336
6337                 /* ::replaceData() */
6338                 V_VT(&v) = VT_BSTR;
6339                 V_BSTR(&v) = SysAllocString(szstr1);
6340                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6341                 ok(hr == S_OK, "ret %08x\n", hr );
6342                 VariantClear(&v);
6343
6344                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6345                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6346                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6347                 ok(hr == S_OK, "ret %08x\n", hr );
6348                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6349                 SysFreeString(str);
6350
6351                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6352                 ok(hr == S_OK, "ret %08x\n", hr );
6353                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6354                 ok(hr == S_OK, "ret %08x\n", hr );
6355                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6356                 SysFreeString(str);
6357
6358                 /* NULL pointer means delete */
6359                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6360                 ok(hr == S_OK, "ret %08x\n", hr );
6361                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6362                 ok(hr == S_OK, "ret %08x\n", hr );
6363                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6364                 SysFreeString(str);
6365
6366                 /* empty string means delete */
6367                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6368                 ok(hr == S_OK, "ret %08x\n", hr );
6369                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6370                 ok(hr == S_OK, "ret %08x\n", hr );
6371                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6372                 SysFreeString(str);
6373
6374                 /* zero count means insert */
6375                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6376                 ok(hr == S_OK, "ret %08x\n", hr );
6377                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6378                 ok(hr == S_OK, "ret %08x\n", hr );
6379                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6380                 SysFreeString(str);
6381
6382                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6383                 ok(hr == S_OK, "ret %08x\n", hr );
6384
6385                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6386                 ok(hr == S_OK, "ret %08x\n", hr );
6387                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6388                 ok(hr == S_OK, "ret %08x\n", hr );
6389                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6390                 SysFreeString(str);
6391
6392                 /* nonempty string, count greater than its length */
6393                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6394                 ok(hr == S_OK, "ret %08x\n", hr );
6395                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6396                 ok(hr == S_OK, "ret %08x\n", hr );
6397                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6398                 SysFreeString(str);
6399
6400                 /* nonempty string, count less than its length */
6401                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6402                 ok(hr == S_OK, "ret %08x\n", hr );
6403                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6404                 ok(hr == S_OK, "ret %08x\n", hr );
6405                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6406                 SysFreeString(str);
6407
6408                 IXMLDOMCDATASection_Release(pCDataSec);
6409             }
6410
6411             /* Document Fragments */
6412             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6413             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6414
6415             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6416             ok(hr == S_OK, "ret %08x\n", hr );
6417             if(hr == S_OK)
6418             {
6419                 IXMLDOMNode *node;
6420
6421                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6422                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6423
6424                 node = (IXMLDOMNode *)0x1;
6425                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6426                 ok(hr == S_FALSE, "ret %08x\n", hr );
6427                 ok(node == NULL, "expected NULL, got %p\n", node);
6428
6429                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6430                 ok(hr == S_OK, "ret %08x\n", hr );
6431
6432                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6433                 ok(hr == S_OK, "ret %08x\n", hr );
6434                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6435                 SysFreeString(str);
6436
6437                 /* test next Sibling*/
6438                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6439                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6440
6441                 node = (IXMLDOMNode *)0x1;
6442                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6443                 ok(hr == S_FALSE, "ret %08x\n", hr );
6444                 ok(node == NULL, "next sibling not NULL\n");
6445
6446                 /* test Previous Sibling*/
6447                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6448                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6449
6450                 node = (IXMLDOMNode *)0x1;
6451                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6452                 ok(hr == S_FALSE, "ret %08x\n", hr );
6453                 ok(node == NULL, "previous sibling not NULL\n");
6454
6455                 IXMLDOMDocumentFragment_Release(pDocFrag);
6456             }
6457
6458             /* Entity References */
6459             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6460             ok(hr == E_FAIL, "ret %08x\n", hr );
6461             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6462             ok(hr == E_FAIL, "ret %08x\n", hr );
6463
6464             str = SysAllocString(szEntityRef);
6465             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6466             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6467
6468             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6469             SysFreeString(str);
6470             ok(hr == S_OK, "ret %08x\n", hr );
6471             if(hr == S_OK)
6472             {
6473                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6474                 ok(hr == S_OK, "ret %08x\n", hr );
6475
6476                 /* test get_xml*/
6477                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6478                 ok(hr == S_OK, "ret %08x\n", hr );
6479                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6480                 SysFreeString(str);
6481
6482                 IXMLDOMEntityReference_Release(pEntityRef);
6483             }
6484
6485             IXMLDOMElement_Release( pRoot );
6486         }
6487     }
6488
6489     IXMLDOMDocument_Release(doc);
6490
6491     free_bstrs();
6492 }
6493
6494 static void test_nodeTypeTests( void )
6495 {
6496     IXMLDOMDocument *doc = NULL;
6497     IXMLDOMElement *pRoot;
6498     IXMLDOMElement *pElement;
6499     HRESULT hr;
6500
6501     doc = create_document(&IID_IXMLDOMDocument);
6502     if (!doc) return;
6503
6504     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6505     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6506
6507     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6508     ok(hr == S_OK, "ret %08x\n", hr );
6509     if(hr == S_OK)
6510     {
6511         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6512         ok(hr == S_OK, "ret %08x\n", hr );
6513         if(hr == S_OK)
6514         {
6515             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
6516             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6517
6518             /* Invalid Value */
6519             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
6520             ok(hr == E_FAIL, "ret %08x\n", hr );
6521
6522             /* NOTE:
6523              *   The name passed into put_dataType is case-insensitive. So many of the names
6524              *     have been changed to reflect this.
6525              */
6526             /* Boolean */
6527             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
6528             ok(hr == S_OK, "ret %08x\n", hr );
6529             if(hr == S_OK)
6530             {
6531                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6532
6533                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
6534                 ok(hr == S_OK, "ret %08x\n", hr );
6535
6536                 IXMLDOMElement_Release(pElement);
6537             }
6538
6539             /* String */
6540             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
6541             ok(hr == S_OK, "ret %08x\n", hr );
6542             if(hr == S_OK)
6543             {
6544                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6545
6546                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
6547                 ok(hr == S_OK, "ret %08x\n", hr );
6548
6549                 IXMLDOMElement_Release(pElement);
6550             }
6551
6552             /* Number */
6553             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
6554             ok(hr == S_OK, "ret %08x\n", hr );
6555             if(hr == S_OK)
6556             {
6557                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6558
6559                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
6560                 ok(hr == S_OK, "ret %08x\n", hr );
6561
6562                 IXMLDOMElement_Release(pElement);
6563             }
6564
6565             /* Int */
6566             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
6567             ok(hr == S_OK, "ret %08x\n", hr );
6568             if(hr == S_OK)
6569             {
6570                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6571
6572                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
6573                 ok(hr == S_OK, "ret %08x\n", hr );
6574
6575                 IXMLDOMElement_Release(pElement);
6576             }
6577
6578             /* Fixed */
6579             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
6580             ok(hr == S_OK, "ret %08x\n", hr );
6581             if(hr == S_OK)
6582             {
6583                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6584
6585                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
6586                 ok(hr == S_OK, "ret %08x\n", hr );
6587
6588                 IXMLDOMElement_Release(pElement);
6589             }
6590
6591             /* DateTime */
6592             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
6593             ok(hr == S_OK, "ret %08x\n", hr );
6594             if(hr == S_OK)
6595             {
6596                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6597
6598                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
6599                 ok(hr == S_OK, "ret %08x\n", hr );
6600
6601                 IXMLDOMElement_Release(pElement);
6602             }
6603
6604             /* DateTime TZ */
6605             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
6606             ok(hr == S_OK, "ret %08x\n", hr );
6607             if(hr == S_OK)
6608             {
6609                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6610
6611                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6612                 ok(hr == S_OK, "ret %08x\n", hr );
6613
6614                 IXMLDOMElement_Release(pElement);
6615             }
6616
6617             /* Date */
6618             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
6619             ok(hr == S_OK, "ret %08x\n", hr );
6620             if(hr == S_OK)
6621             {
6622                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6623
6624                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
6625                 ok(hr == S_OK, "ret %08x\n", hr );
6626
6627                 IXMLDOMElement_Release(pElement);
6628             }
6629
6630             /* Time */
6631             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
6632             ok(hr == S_OK, "ret %08x\n", hr );
6633             if(hr == S_OK)
6634             {
6635                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6636
6637                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
6638                 ok(hr == S_OK, "ret %08x\n", hr );
6639
6640                 IXMLDOMElement_Release(pElement);
6641             }
6642
6643             /* Time.tz */
6644             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
6645             ok(hr == S_OK, "ret %08x\n", hr );
6646             if(hr == S_OK)
6647             {
6648                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6649
6650                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
6651                 ok(hr == S_OK, "ret %08x\n", hr );
6652
6653                 IXMLDOMElement_Release(pElement);
6654             }
6655
6656             /* I1 */
6657             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
6658             ok(hr == S_OK, "ret %08x\n", hr );
6659             if(hr == S_OK)
6660             {
6661                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6662
6663                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
6664                 ok(hr == S_OK, "ret %08x\n", hr );
6665
6666                 IXMLDOMElement_Release(pElement);
6667             }
6668
6669             /* I2 */
6670             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
6671             ok(hr == S_OK, "ret %08x\n", hr );
6672             if(hr == S_OK)
6673             {
6674                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6675
6676                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
6677                 ok(hr == S_OK, "ret %08x\n", hr );
6678
6679                 IXMLDOMElement_Release(pElement);
6680             }
6681
6682             /* I4 */
6683             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
6684             ok(hr == S_OK, "ret %08x\n", hr );
6685             if(hr == S_OK)
6686             {
6687                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6688
6689                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
6690                 ok(hr == S_OK, "ret %08x\n", hr );
6691
6692                 IXMLDOMElement_Release(pElement);
6693             }
6694
6695             /* UI1 */
6696             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
6697             ok(hr == S_OK, "ret %08x\n", hr );
6698             if(hr == S_OK)
6699             {
6700                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6701
6702                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
6703                 ok(hr == S_OK, "ret %08x\n", hr );
6704
6705                 IXMLDOMElement_Release(pElement);
6706             }
6707
6708             /* UI2 */
6709             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
6710             ok(hr == S_OK, "ret %08x\n", hr );
6711             if(hr == S_OK)
6712             {
6713                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6714
6715                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
6716                 ok(hr == S_OK, "ret %08x\n", hr );
6717
6718                 IXMLDOMElement_Release(pElement);
6719             }
6720
6721             /* UI4 */
6722             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
6723             ok(hr == S_OK, "ret %08x\n", hr );
6724             if(hr == S_OK)
6725             {
6726                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6727
6728                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
6729                 ok(hr == S_OK, "ret %08x\n", hr );
6730
6731                 IXMLDOMElement_Release(pElement);
6732             }
6733
6734             /* r4 */
6735             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
6736             ok(hr == S_OK, "ret %08x\n", hr );
6737             if(hr == S_OK)
6738             {
6739                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6740
6741                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
6742                 ok(hr == S_OK, "ret %08x\n", hr );
6743
6744                 IXMLDOMElement_Release(pElement);
6745             }
6746
6747             /* r8 */
6748             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
6749             ok(hr == S_OK, "ret %08x\n", hr );
6750             if(hr == S_OK)
6751             {
6752                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6753
6754                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
6755                 ok(hr == S_OK, "ret %08x\n", hr );
6756
6757                 IXMLDOMElement_Release(pElement);
6758             }
6759
6760             /* float */
6761             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
6762             ok(hr == S_OK, "ret %08x\n", hr );
6763             if(hr == S_OK)
6764             {
6765                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6766
6767                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
6768                 ok(hr == S_OK, "ret %08x\n", hr );
6769
6770                 IXMLDOMElement_Release(pElement);
6771             }
6772
6773             /* uuid */
6774             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
6775             ok(hr == S_OK, "ret %08x\n", hr );
6776             if(hr == S_OK)
6777             {
6778                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6779
6780                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
6781                 ok(hr == S_OK, "ret %08x\n", hr );
6782
6783                 IXMLDOMElement_Release(pElement);
6784             }
6785
6786             /* bin.hex */
6787             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
6788             ok(hr == S_OK, "ret %08x\n", hr );
6789             if(hr == S_OK)
6790             {
6791                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6792
6793                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
6794                 ok(hr == S_OK, "ret %08x\n", hr );
6795
6796                 IXMLDOMElement_Release(pElement);
6797             }
6798
6799             /* bin.base64 */
6800             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
6801             ok(hr == S_OK, "ret %08x\n", hr );
6802             if(hr == S_OK)
6803             {
6804                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6805
6806                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
6807                 ok(hr == S_OK, "ret %08x\n", hr );
6808
6809                 IXMLDOMElement_Release(pElement);
6810             }
6811
6812             /* Check changing types */
6813             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
6814             ok(hr == S_OK, "ret %08x\n", hr );
6815             if(hr == S_OK)
6816             {
6817                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6818
6819                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6820                 ok(hr == S_OK, "ret %08x\n", hr );
6821
6822                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
6823                 ok(hr == S_OK, "ret %08x\n", hr );
6824
6825                 IXMLDOMElement_Release(pElement);
6826             }
6827
6828             IXMLDOMElement_Release(pRoot);
6829         }
6830     }
6831
6832     IXMLDOMDocument_Release(doc);
6833
6834     free_bstrs();
6835 }
6836
6837 static void test_save(void)
6838 {
6839     IXMLDOMDocument *doc, *doc2;
6840     IXMLDOMElement *root;
6841     VARIANT file, vDoc;
6842     BSTR sOrig, sNew, filename;
6843     char buffer[100];
6844     DWORD read = 0;
6845     HANDLE hfile;
6846     HRESULT hr;
6847
6848     doc = create_document(&IID_IXMLDOMDocument);
6849     if (!doc) return;
6850
6851     doc2 = create_document(&IID_IXMLDOMDocument);
6852     if (!doc2)
6853     {
6854         IXMLDOMDocument_Release(doc);
6855         return;
6856     }
6857
6858     /* save to IXMLDOMDocument */
6859     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6860     EXPECT_HR(hr, S_OK);
6861
6862     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6863     EXPECT_HR(hr, S_OK);
6864
6865     V_VT(&vDoc) = VT_UNKNOWN;
6866     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
6867
6868     hr = IXMLDOMDocument_save(doc, vDoc);
6869     EXPECT_HR(hr, S_OK);
6870
6871     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
6872     EXPECT_HR(hr, S_OK);
6873
6874     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
6875     EXPECT_HR(hr, S_OK);
6876
6877     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
6878
6879     SysFreeString(sOrig);
6880     SysFreeString(sNew);
6881
6882     IXMLDOMElement_Release(root);
6883     IXMLDOMDocument_Release(doc2);
6884
6885     /* save to path */
6886     V_VT(&file) = VT_BSTR;
6887     V_BSTR(&file) = _bstr_("test.xml");
6888
6889     hr = IXMLDOMDocument_save(doc, file);
6890     EXPECT_HR(hr, S_OK);
6891
6892     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6893     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6894     if(hfile == INVALID_HANDLE_VALUE) return;
6895
6896     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6897     ok(read != 0, "could not read file\n");
6898     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6899
6900     CloseHandle(hfile);
6901     DeleteFile("test.xml");
6902
6903     /* save to path VT_BSTR | VT_BYREF */
6904     filename = _bstr_("test.xml");
6905     V_VT(&file) = VT_BSTR | VT_BYREF;
6906     V_BSTRREF(&file) = &filename;
6907
6908     hr = IXMLDOMDocument_save(doc, file);
6909     EXPECT_HR(hr, S_OK);
6910
6911     IXMLDOMDocument_Release(doc);
6912
6913     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6914     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6915     if(hfile == INVALID_HANDLE_VALUE) return;
6916
6917     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6918     ok(read != 0, "could not read file\n");
6919     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6920
6921     CloseHandle(hfile);
6922     DeleteFile("test.xml");
6923     free_bstrs();
6924 }
6925
6926 static void test_testTransforms(void)
6927 {
6928     IXMLDOMDocument *doc, *docSS;
6929     IXMLDOMNode *pNode;
6930     VARIANT_BOOL bSucc;
6931
6932     HRESULT hr;
6933
6934     doc = create_document(&IID_IXMLDOMDocument);
6935     if (!doc) return;
6936
6937     docSS = create_document(&IID_IXMLDOMDocument);
6938     if (!docSS)
6939     {
6940         IXMLDOMDocument_Release(doc);
6941         return;
6942     }
6943
6944     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
6945     ok(hr == S_OK, "ret %08x\n", hr );
6946
6947     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
6948     ok(hr == S_OK, "ret %08x\n", hr );
6949
6950     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
6951     ok(hr == S_OK, "ret %08x\n", hr );
6952     if(hr == S_OK)
6953     {
6954         BSTR bOut;
6955
6956         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
6957         ok(hr == S_OK, "ret %08x\n", hr );
6958         if(hr == S_OK)
6959         {
6960             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
6961             SysFreeString(bOut);
6962         }
6963
6964         IXMLDOMNode_Release(pNode);
6965     }
6966
6967     IXMLDOMDocument_Release(docSS);
6968     IXMLDOMDocument_Release(doc);
6969
6970     free_bstrs();
6971 }
6972
6973 static void test_Namespaces(void)
6974 {
6975     static const CHAR szNamespacesXML[] =
6976         "<?xml version=\"1.0\"?>\n"
6977         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
6978         "  <XMI.content>"
6979         "    <Model:Package name=\"WinePackage\" />"
6980         "  </XMI.content>"
6981         "</XMI>";
6982
6983     IXMLDOMDocument *doc;
6984     IXMLDOMElement *elem;
6985     IXMLDOMNode *node;
6986     IXMLDOMNode *pNode2 = NULL;
6987     VARIANT_BOOL bSucc;
6988     VARIANT var;
6989     HRESULT hr;
6990     BSTR str;
6991
6992     doc = create_document(&IID_IXMLDOMDocument);
6993     if (!doc) return;
6994
6995     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szNamespacesXML), &bSucc);
6996     ok(hr == S_OK, "ret %08x\n", hr );
6997     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6998
6999     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7000     ok(hr == S_OK, "ret %08x\n", hr );
7001     if(hr == S_OK)
7002     {
7003         hr = IXMLDOMNode_get_firstChild( node, &pNode2 );
7004         ok( hr == S_OK, "ret %08x\n", hr );
7005         ok( pNode2 != NULL, "pNode2 == NULL\n");
7006
7007         /* Test get_prefix */
7008         hr = IXMLDOMNode_get_prefix(pNode2, NULL);
7009         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
7010         /* NOTE: Need to test that arg2 gets cleared on Error. */
7011
7012         hr = IXMLDOMNode_get_prefix(pNode2, &str);
7013         ok( hr == S_OK, "ret %08x\n", hr );
7014         ok( !lstrcmpW( str, _bstr_("Model")), "incorrect prefix string\n");
7015         SysFreeString(str);
7016
7017         hr = IXMLDOMNode_get_nodeName(pNode2, &str);
7018         ok( hr == S_OK, "ret %08x\n", hr );
7019         todo_wine ok( !lstrcmpW( str, _bstr_("Model:Package")), "incorrect nodeName string\n");
7020         SysFreeString(str);
7021
7022         /* Test get_namespaceURI */
7023         hr = IXMLDOMNode_get_namespaceURI(pNode2, NULL);
7024         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
7025         /* NOTE: Need to test that arg2 gets cleared on Error. */
7026
7027         hr = IXMLDOMNode_get_namespaceURI(pNode2, &str);
7028         ok( hr == S_OK, "ret %08x\n", hr );
7029         ok( !lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "incorrect namespaceURI string\n");
7030         SysFreeString(str);
7031
7032         IXMLDOMNode_Release(pNode2);
7033         IXMLDOMNode_Release(node);
7034     }
7035
7036     IXMLDOMDocument_Release(doc);
7037
7038     /* create on element and try to alter namespace after that */
7039     doc = create_document(&IID_IXMLDOMDocument);
7040     if (!doc) return;
7041
7042     V_VT(&var) = VT_I2;
7043     V_I2(&var) = NODE_ELEMENT;
7044
7045     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7046     EXPECT_HR(hr, S_OK);
7047
7048     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7049     EXPECT_HR(hr, S_OK);
7050
7051     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7052     EXPECT_HR(hr, S_OK);
7053
7054     V_VT(&var) = VT_BSTR;
7055     V_BSTR(&var) = _bstr_("ns/uri2");
7056
7057     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7058     EXPECT_HR(hr, E_INVALIDARG);
7059
7060     V_VT(&var) = VT_BSTR;
7061     V_BSTR(&var) = _bstr_("ns/uri");
7062
7063     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7064     EXPECT_HR(hr, S_OK);
7065
7066     hr = IXMLDOMElement_get_xml(elem, &str);
7067     EXPECT_HR(hr, S_OK);
7068     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7069     SysFreeString(str);
7070
7071     IXMLDOMElement_Release(elem);
7072     IXMLDOMDocument_Release(doc);
7073
7074     /* create on element and try to alter namespace after that */
7075     doc = create_document_version(60, &IID_IXMLDOMDocument);
7076     if (!doc) return;
7077
7078     V_VT(&var) = VT_I2;
7079     V_I2(&var) = NODE_ELEMENT;
7080
7081     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7082     EXPECT_HR(hr, S_OK);
7083
7084     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7085     EXPECT_HR(hr, S_OK);
7086
7087     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7088     EXPECT_HR(hr, S_OK);
7089
7090     /* try same prefix, different uri */
7091     V_VT(&var) = VT_BSTR;
7092     V_BSTR(&var) = _bstr_("ns/uri2");
7093
7094     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7095     EXPECT_HR(hr, E_INVALIDARG);
7096
7097     /* try same prefix and uri */
7098     V_VT(&var) = VT_BSTR;
7099     V_BSTR(&var) = _bstr_("ns/uri");
7100
7101     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7102     EXPECT_HR(hr, S_OK);
7103
7104     hr = IXMLDOMElement_get_xml(elem, &str);
7105     EXPECT_HR(hr, S_OK);
7106     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7107     SysFreeString(str);
7108
7109     IXMLDOMElement_Release(elem);
7110     IXMLDOMDocument_Release(doc);
7111
7112     free_bstrs();
7113 }
7114
7115 static void test_FormattingXML(void)
7116 {
7117     IXMLDOMDocument *doc;
7118     IXMLDOMElement *pElement;
7119     VARIANT_BOOL bSucc;
7120     HRESULT hr;
7121     BSTR str;
7122     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7123     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7124
7125     doc = create_document(&IID_IXMLDOMDocument);
7126     if (!doc) return;
7127
7128     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7129     ok(hr == S_OK, "ret %08x\n", hr );
7130     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7131
7132     if(bSucc == VARIANT_TRUE)
7133     {
7134         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7135         ok(hr == S_OK, "ret %08x\n", hr );
7136         if(hr == S_OK)
7137         {
7138             hr = IXMLDOMElement_get_xml(pElement, &str);
7139             ok(hr == S_OK, "ret %08x\n", hr );
7140             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7141             SysFreeString(str);
7142
7143             IXMLDOMElement_Release(pElement);
7144         }
7145     }
7146
7147     IXMLDOMDocument_Release(doc);
7148
7149     free_bstrs();
7150 }
7151
7152 typedef struct _nodetypedvalue_t {
7153     const char *name;
7154     VARTYPE type;
7155     const char *value; /* value in string format */
7156 } nodetypedvalue_t;
7157
7158 static const nodetypedvalue_t get_nodetypedvalue[] = {
7159     { "root/string",    VT_BSTR, "Wine" },
7160     { "root/string2",   VT_BSTR, "String" },
7161     { "root/number",    VT_BSTR, "12.44" },
7162     { "root/number2",   VT_BSTR, "-3.71e3" },
7163     { "root/int",       VT_I4,   "-13" },
7164     { "root/fixed",     VT_CY,   "7322.9371" },
7165     { "root/bool",      VT_BOOL, "-1" },
7166     { "root/datetime",  VT_DATE, "40135.14" },
7167     { "root/datetimetz",VT_DATE, "37813.59" },
7168     { "root/date",      VT_DATE, "665413" },
7169     { "root/time",      VT_DATE, "0.5813889" },
7170     { "root/timetz",    VT_DATE, "1.112512" },
7171     { "root/i1",        VT_I1,   "-13" },
7172     { "root/i2",        VT_I2,   "31915" },
7173     { "root/i4",        VT_I4,   "-312232" },
7174     { "root/ui1",       VT_UI1,  "123" },
7175     { "root/ui2",       VT_UI2,  "48282" },
7176     { "root/ui4",       VT_UI4,  "949281" },
7177     { "root/r4",        VT_R4,   "213124" },
7178     { "root/r8",        VT_R8,   "0.412" },
7179     { "root/float",     VT_R8,   "41221.421" },
7180     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7181     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7182     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7183     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7184     { 0 }
7185 };
7186
7187 static void test_nodeTypedValue(void)
7188 {
7189     const nodetypedvalue_t *entry = get_nodetypedvalue;
7190     IXMLDOMDocumentType *doctype, *doctype2;
7191     IXMLDOMProcessingInstruction *pi;
7192     IXMLDOMDocumentFragment *frag;
7193     IXMLDOMDocument *doc, *doc2;
7194     IXMLDOMCDATASection *cdata;
7195     IXMLDOMComment *comment;
7196     IXMLDOMNode *node;
7197     VARIANT_BOOL b;
7198     VARIANT value;
7199     HRESULT hr;
7200
7201     doc = create_document(&IID_IXMLDOMDocument);
7202     if (!doc) return;
7203
7204     b = VARIANT_FALSE;
7205     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7206     ok(hr == S_OK, "ret %08x\n", hr );
7207     ok(b == VARIANT_TRUE, "got %d\n", b);
7208
7209     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7210     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7211
7212     V_VT(&value) = VT_BSTR;
7213     V_BSTR(&value) = NULL;
7214     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7215     ok(hr == S_FALSE, "ret %08x\n", hr );
7216     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7217
7218     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7219     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7220
7221     V_VT(&value) = VT_EMPTY;
7222     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7223     ok(hr == S_FALSE, "ret %08x\n", hr );
7224     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7225
7226     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7227     ok(hr == S_OK, "ret %08x\n", hr );
7228
7229     V_VT(&value) = VT_BSTR;
7230     V_BSTR(&value) = NULL;
7231     hr = IXMLDOMNode_get_nodeValue(node, &value);
7232     ok(hr == S_FALSE, "ret %08x\n", hr );
7233     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7234
7235     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7236     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7237
7238     IXMLDOMNode_Release(node);
7239
7240     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7241     ok(hr == S_OK, "ret %08x\n", hr );
7242     {
7243         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7244
7245         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7246         ok(hr == S_OK, "ret %08x\n", hr );
7247         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7248         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7249         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7250             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7251         VariantClear(&value);
7252         IXMLDOMNode_Release(node);
7253     }
7254
7255     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7256     ok(hr == S_OK, "ret %08x\n", hr );
7257     {
7258         V_VT(&value) = VT_NULL;
7259         V_BSTR(&value) = (void*)0xdeadbeef;
7260         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7261         ok(hr == S_OK, "ret %08x\n", hr );
7262         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7263         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7264         IXMLDOMProcessingInstruction_Release(pi);
7265         VariantClear(&value);
7266     }
7267
7268     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7269     ok(hr == S_OK, "ret %08x\n", hr );
7270     {
7271         V_VT(&value) = VT_NULL;
7272         V_BSTR(&value) = (void*)0xdeadbeef;
7273         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7274         ok(hr == S_OK, "ret %08x\n", hr );
7275         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7276         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7277         IXMLDOMCDATASection_Release(cdata);
7278         VariantClear(&value);
7279     }
7280
7281     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7282     ok(hr == S_OK, "ret %08x\n", hr );
7283     {
7284         V_VT(&value) = VT_NULL;
7285         V_BSTR(&value) = (void*)0xdeadbeef;
7286         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7287         ok(hr == S_OK, "ret %08x\n", hr );
7288         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7289         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7290         IXMLDOMComment_Release(comment);
7291         VariantClear(&value);
7292     }
7293
7294     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7295     ok(hr == S_OK, "ret %08x\n", hr );
7296     {
7297         V_VT(&value) = VT_EMPTY;
7298         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7299         ok(hr == S_FALSE, "ret %08x\n", hr );
7300         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7301         IXMLDOMDocumentFragment_Release(frag);
7302     }
7303
7304     doc2 = create_document(&IID_IXMLDOMDocument);
7305
7306     b = VARIANT_FALSE;
7307     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7308     ok(hr == S_OK, "ret %08x\n", hr );
7309     ok(b == VARIANT_TRUE, "got %d\n", b);
7310
7311     EXPECT_REF(doc2, 1);
7312
7313     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7314     ok(hr == S_OK, "ret %08x\n", hr );
7315
7316     EXPECT_REF(doc2, 1);
7317     todo_wine EXPECT_REF(doctype, 2);
7318
7319     {
7320         V_VT(&value) = VT_EMPTY;
7321         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7322         ok(hr == S_FALSE, "ret %08x\n", hr );
7323         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7324     }
7325
7326     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7327     ok(hr == S_OK, "ret %08x\n", hr );
7328     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7329
7330     IXMLDOMDocumentType_Release(doctype2);
7331     IXMLDOMDocumentType_Release(doctype);
7332
7333     IXMLDOMDocument_Release(doc2);
7334
7335     while (entry->name)
7336     {
7337         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7338         ok(hr == S_OK, "ret %08x\n", hr );
7339
7340         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7341         ok(hr == S_OK, "ret %08x\n", hr );
7342         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7343
7344         if (entry->type == (VT_ARRAY|VT_UI1))
7345         {
7346             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7347                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7348         }
7349
7350         if (entry->type != VT_BSTR)
7351         {
7352            if (entry->type == VT_DATE ||
7353                entry->type == VT_R8 ||
7354                entry->type == VT_CY)
7355            {
7356                if (entry->type == VT_DATE)
7357                {
7358                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7359                    ok(hr == S_OK, "ret %08x\n", hr );
7360                }
7361                hr = VariantChangeTypeEx(&value, &value,
7362                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7363                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7364                ok(hr == S_OK, "ret %08x\n", hr );
7365            }
7366            else
7367            {
7368                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7369                ok(hr == S_OK, "ret %08x\n", hr );
7370            }
7371
7372            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7373            if (entry->type == (VT_ARRAY|VT_UI1))
7374            {
7375                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7376                   "expected %s\n", entry->value);
7377            }
7378            else
7379                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7380                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7381         }
7382         else
7383            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7384                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7385
7386         VariantClear( &value );
7387         IXMLDOMNode_Release(node);
7388
7389         entry++;
7390     }
7391
7392     IXMLDOMDocument_Release(doc);
7393     free_bstrs();
7394 }
7395
7396 static void test_TransformWithLoadingLocalFile(void)
7397 {
7398     IXMLDOMDocument *doc;
7399     IXMLDOMDocument *xsl;
7400     IXMLDOMNode *pNode;
7401     VARIANT_BOOL bSucc;
7402     HRESULT hr;
7403     HANDLE file;
7404     DWORD dwWritten;
7405     char lpPathBuffer[MAX_PATH];
7406     int i;
7407
7408     /* Create a Temp File. */
7409     GetTempPathA(MAX_PATH, lpPathBuffer);
7410     strcat(lpPathBuffer, "customers.xml" );
7411
7412     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7413     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7414     if(file == INVALID_HANDLE_VALUE)
7415         return;
7416
7417     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7418     CloseHandle(file);
7419
7420     /* Correct path to not include a escape character. */
7421     for(i=0; i < strlen(lpPathBuffer); i++)
7422     {
7423         if(lpPathBuffer[i] == '\\')
7424             lpPathBuffer[i] = '/';
7425     }
7426
7427     doc = create_document(&IID_IXMLDOMDocument);
7428     if (!doc) return;
7429
7430     xsl = create_document(&IID_IXMLDOMDocument);
7431     if (!xsl)
7432     {
7433         IXMLDOMDocument2_Release(doc);
7434         return;
7435     }
7436
7437     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7438     ok(hr == S_OK, "ret %08x\n", hr );
7439     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7440     if(bSucc == VARIANT_TRUE)
7441     {
7442         BSTR sXSL;
7443         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7444         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7445         BSTR sFileName = _bstr_(lpPathBuffer);
7446         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7447
7448         sXSL = SysAllocStringLen(NULL, nLegnth);
7449         lstrcpyW(sXSL, sPart1);
7450         lstrcatW(sXSL, sFileName);
7451         lstrcatW(sXSL, sPart2);
7452
7453         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7454         ok(hr == S_OK, "ret %08x\n", hr );
7455         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7456         if(bSucc == VARIANT_TRUE)
7457         {
7458             BSTR sResult;
7459
7460             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7461             ok(hr == S_OK, "ret %08x\n", hr );
7462             if(hr == S_OK)
7463             {
7464                 /* This will load the temp file via the XSL */
7465                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7466                 ok(hr == S_OK, "ret %08x\n", hr );
7467                 if(hr == S_OK)
7468                 {
7469                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7470                     SysFreeString(sResult);
7471                 }
7472
7473                 IXMLDOMNode_Release(pNode);
7474             }
7475         }
7476
7477         SysFreeString(sXSL);
7478     }
7479
7480     IXMLDOMDocument_Release(doc);
7481     IXMLDOMDocument_Release(xsl);
7482
7483     DeleteFile(lpPathBuffer);
7484     free_bstrs();
7485 }
7486
7487 static void test_put_nodeValue(void)
7488 {
7489     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7490     IXMLDOMDocument *doc;
7491     IXMLDOMText *text;
7492     IXMLDOMEntityReference *entityref;
7493     IXMLDOMAttribute *attr;
7494     IXMLDOMNode *node;
7495     HRESULT hr;
7496     VARIANT data, type;
7497
7498     doc = create_document(&IID_IXMLDOMDocument);
7499     if (!doc) return;
7500
7501     /* test for unsupported types */
7502     /* NODE_DOCUMENT */
7503     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7504     ok(hr == S_OK, "ret %08x\n", hr );
7505     V_VT(&data) = VT_BSTR;
7506     V_BSTR(&data) = _bstr_("one two three");
7507     hr = IXMLDOMNode_put_nodeValue(node, data);
7508     ok(hr == E_FAIL, "ret %08x\n", hr );
7509     IXMLDOMNode_Release(node);
7510
7511     /* NODE_DOCUMENT_FRAGMENT */
7512     V_VT(&type) = VT_I1;
7513     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7514     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7515     ok(hr == S_OK, "ret %08x\n", hr );
7516     V_VT(&data) = VT_BSTR;
7517     V_BSTR(&data) = _bstr_("one two three");
7518     hr = IXMLDOMNode_put_nodeValue(node, data);
7519     ok(hr == E_FAIL, "ret %08x\n", hr );
7520     IXMLDOMNode_Release(node);
7521
7522     /* NODE_ELEMENT */
7523     V_VT(&type) = VT_I1;
7524     V_I1(&type) = NODE_ELEMENT;
7525     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7526     ok(hr == S_OK, "ret %08x\n", hr );
7527     V_VT(&data) = VT_BSTR;
7528     V_BSTR(&data) = _bstr_("one two three");
7529     hr = IXMLDOMNode_put_nodeValue(node, data);
7530     ok(hr == E_FAIL, "ret %08x\n", hr );
7531     IXMLDOMNode_Release(node);
7532
7533     /* NODE_ENTITY_REFERENCE */
7534     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7535     ok(hr == S_OK, "ret %08x\n", hr );
7536
7537     V_VT(&data) = VT_BSTR;
7538     V_BSTR(&data) = _bstr_("one two three");
7539     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7540     ok(hr == E_FAIL, "ret %08x\n", hr );
7541
7542     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7543     ok(hr == S_OK, "ret %08x\n", hr );
7544     V_VT(&data) = VT_BSTR;
7545     V_BSTR(&data) = _bstr_("one two three");
7546     hr = IXMLDOMNode_put_nodeValue(node, data);
7547     ok(hr == E_FAIL, "ret %08x\n", hr );
7548     IXMLDOMNode_Release(node);
7549     IXMLDOMEntityReference_Release(entityref);
7550
7551     /* supported types */
7552     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7553     ok(hr == S_OK, "ret %08x\n", hr );
7554     V_VT(&data) = VT_BSTR;
7555     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7556     hr = IXMLDOMText_put_nodeValue(text, data);
7557     ok(hr == S_OK, "ret %08x\n", hr );
7558     IXMLDOMText_Release(text);
7559
7560     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7561     ok(hr == S_OK, "ret %08x\n", hr );
7562     V_VT(&data) = VT_BSTR;
7563     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7564     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7565     ok(hr == S_OK, "ret %08x\n", hr );
7566     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7567     ok(hr == S_OK, "ret %08x\n", hr );
7568     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7569         wine_dbgstr_w(V_BSTR(&data)));
7570     VariantClear(&data);
7571     IXMLDOMAttribute_Release(attr);
7572
7573     free_bstrs();
7574
7575     IXMLDOMDocument_Release(doc);
7576 }
7577
7578 static void test_document_IObjectSafety(void)
7579 {
7580     IXMLDOMDocument *doc;
7581     IObjectSafety *safety;
7582     HRESULT hr;
7583
7584     doc = create_document(&IID_IXMLDOMDocument);
7585     if (!doc) return;
7586
7587     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7588     ok(hr == S_OK, "ret %08x\n", hr );
7589
7590     test_IObjectSafety_common(safety);
7591
7592     IObjectSafety_Release(safety);
7593
7594     IXMLDOMDocument_Release(doc);
7595 }
7596
7597 typedef struct _property_test_t {
7598     const GUID *guid;
7599     const char *clsid;
7600     const char *property;
7601     const char *value;
7602 } property_test_t;
7603
7604 static const property_test_t properties_test_data[] = {
7605     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7606     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7607     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7608     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7609     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7610     { 0 }
7611 };
7612
7613 static void test_default_properties(void)
7614 {
7615     const property_test_t *entry = properties_test_data;
7616
7617     while (entry->guid)
7618     {
7619         IXMLDOMDocument2 *doc;
7620         VARIANT var;
7621         HRESULT hr;
7622
7623         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7624         if (hr != S_OK)
7625         {
7626             win_skip("can't create %s instance\n", entry->clsid);
7627             entry++;
7628             continue;
7629         }
7630
7631         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7632         ok(hr == S_OK, "got 0x%08x\n", hr);
7633         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7634            entry->value, entry->clsid);
7635         VariantClear(&var);
7636
7637         IXMLDOMDocument2_Release(doc);
7638
7639         entry++;
7640     }
7641 }
7642
7643 typedef struct {
7644     const char *query;
7645     const char *list;
7646 } xslpattern_test_t;
7647
7648 static const xslpattern_test_t xslpattern_test[] = {
7649     { "root//elem[0]", "E1.E2.D1" },
7650     { "root//elem[index()=1]", "E2.E2.D1" },
7651     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7652     { "root//elem[end()]", "E4.E2.D1" },
7653     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7654     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7655     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7656     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7657     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7658     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7659     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7660     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7661     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7662     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7663     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7664     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7665     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7666     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7667     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7668     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7669     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7670     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7671     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7672     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7673     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7674     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7675     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7676     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7677     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7678     { NULL }
7679 };
7680
7681 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7682     /* prefixes don't need to be registered, you may use them as they are in the doc */
7683     { "//bar:x", "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1" },
7684     /* prefixes must be explicitly specified in the name */
7685     { "//foo:elem", "" },
7686     { "//foo:c", "E3.E4.E2.D1" },
7687     { NULL }
7688 };
7689
7690 static const xslpattern_test_t xslpattern_test_func[] = {
7691     { "attribute()", "" },
7692     { "attribute('depth')", "" },
7693     { "root/attribute('depth')", "A'depth'.E3.D1" },
7694     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7695     { "//x//attribute(id)", NULL },
7696     { "//x//attribute('id')", "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1" },
7697     { "comment()", "C2.D1" },
7698     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7699     { "element()", "E3.D1" },
7700     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7701     { "//element(a)", NULL },
7702     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7703     { "node()", "P1.D1 C2.D1 E3.D1" },
7704     { "//x/node()", "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7705     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7706     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7707     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7708     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7709     { "pi()", "P1.D1" },
7710     { "//y/pi()", "P1.E4.E3.D1" },
7711     { "root/textnode()", "T2.E3.D1" },
7712     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7713     { NULL }
7714 };
7715
7716 static void test_XSLPattern(void)
7717 {
7718     const xslpattern_test_t *ptr = xslpattern_test;
7719     IXMLDOMDocument2 *doc;
7720     IXMLDOMNodeList *list;
7721     VARIANT_BOOL b;
7722     HRESULT hr;
7723     LONG len;
7724
7725     doc = create_document(&IID_IXMLDOMDocument2);
7726     if (!doc) return;
7727
7728     b = VARIANT_FALSE;
7729     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7730     EXPECT_HR(hr, S_OK);
7731     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7732
7733     /* switch to XSLPattern */
7734     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7735     EXPECT_HR(hr, S_OK);
7736
7737     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7738     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7739     EXPECT_HR(hr, S_OK);
7740
7741     len = 0;
7742     hr = IXMLDOMNodeList_get_length(list, &len);
7743     EXPECT_HR(hr, S_OK);
7744     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7745     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7746     IXMLDOMNodeList_Release(list);
7747
7748     while (ptr->query)
7749     {
7750         list = NULL;
7751         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7752         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7753         len = 0;
7754         hr = IXMLDOMNodeList_get_length(list, &len);
7755         ok(len != 0, "query=%s, empty list\n", ptr->query);
7756         if (len)
7757             expect_list_and_release(list, ptr->list);
7758
7759         ptr++;
7760     }
7761
7762     /* namespace handling */
7763     /* no registered namespaces */
7764     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7765     EXPECT_HR(hr, S_OK);
7766
7767     ptr = xslpattern_test_no_ns;
7768     while (ptr->query)
7769     {
7770         list = NULL;
7771         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7772         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7773
7774         if (*ptr->list)
7775         {
7776             len = 0;
7777             hr = IXMLDOMNodeList_get_length(list, &len);
7778             EXPECT_HR(hr, S_OK);
7779             ok(len != 0, "query=%s, empty list\n", ptr->query);
7780         }
7781         else
7782         {
7783             len = 1;
7784             hr = IXMLDOMNodeList_get_length(list, &len);
7785             EXPECT_HR(hr, S_OK);
7786             ok(len == 0, "query=%s, empty list\n", ptr->query);
7787         }
7788         if (len)
7789             expect_list_and_release(list, ptr->list);
7790
7791         ptr++;
7792     }
7793
7794     /* explicitly register prefix foo */
7795     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7796
7797     /* now we get the same behavior as XPath */
7798     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7799     EXPECT_HR(hr, S_OK);
7800     len = 0;
7801     hr = IXMLDOMNodeList_get_length(list, &len);
7802     EXPECT_HR(hr, S_OK);
7803     ok(len != 0, "expected filled list\n");
7804     if (len)
7805         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
7806
7807     /* set prefix foo to some nonexistent namespace */
7808     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
7809     EXPECT_HR(hr, S_OK);
7810
7811     /* the registered prefix takes precedence */
7812     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7813     EXPECT_HR(hr, S_OK);
7814     len = 0;
7815     hr = IXMLDOMNodeList_get_length(list, &len);
7816     EXPECT_HR(hr, S_OK);
7817     ok(len == 0, "expected empty list\n");
7818     IXMLDOMNodeList_Release(list);
7819
7820     IXMLDOMDocument2_Release(doc);
7821
7822     doc = create_document(&IID_IXMLDOMDocument2);
7823     if (!doc) return;
7824
7825     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
7826     EXPECT_HR(hr, S_OK);
7827     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7828
7829     ptr = xslpattern_test_func;
7830     while (ptr->query)
7831     {
7832         list = NULL;
7833         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7834         if (ptr->list)
7835         {
7836             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7837             len = 0;
7838             hr = IXMLDOMNodeList_get_length(list, &len);
7839             if (*ptr->list)
7840             {
7841                 ok(len != 0, "query=%s, empty list\n", ptr->query);
7842                 if (len)
7843                     expect_list_and_release(list, ptr->list);
7844             }
7845             else
7846                 ok(len == 0, "query=%s, filled list\n", ptr->query);
7847         }
7848         else
7849             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7850
7851         ptr++;
7852     }
7853
7854     IXMLDOMDocument2_Release(doc);
7855     free_bstrs();
7856 }
7857
7858 static void test_splitText(void)
7859 {
7860     IXMLDOMCDATASection *cdata;
7861     IXMLDOMElement *root;
7862     IXMLDOMDocument *doc;
7863     IXMLDOMText *text, *text2;
7864     IXMLDOMNode *node;
7865     VARIANT var;
7866     VARIANT_BOOL success;
7867     LONG length;
7868     HRESULT hr;
7869
7870     doc = create_document(&IID_IXMLDOMDocument);
7871     if (!doc) return;
7872
7873     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
7874     ok(hr == S_OK, "got 0x%08x\n", hr);
7875
7876     hr = IXMLDOMDocument_get_documentElement(doc, &root);
7877     ok(hr == S_OK, "got 0x%08x\n", hr);
7878
7879     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
7880     ok(hr == S_OK, "got 0x%08x\n", hr);
7881
7882     V_VT(&var) = VT_EMPTY;
7883     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
7884     ok(hr == S_OK, "got 0x%08x\n", hr);
7885
7886     length = 0;
7887     hr = IXMLDOMCDATASection_get_length(cdata, &length);
7888     ok(hr == S_OK, "got 0x%08x\n", hr);
7889     ok(length > 0, "got %d\n", length);
7890
7891     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
7892     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7893
7894     text = (void*)0xdeadbeef;
7895     /* negative offset */
7896     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
7897     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7898     ok(text == (void*)0xdeadbeef, "got %p\n", text);
7899
7900     text = (void*)0xdeadbeef;
7901     /* offset outside data */
7902     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
7903     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7904     ok(text == 0, "got %p\n", text);
7905
7906     text = (void*)0xdeadbeef;
7907     /* offset outside data */
7908     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
7909     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7910     ok(text == 0, "got %p\n", text);
7911
7912     /* no empty node created */
7913     node = (void*)0xdeadbeef;
7914     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7915     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7916     ok(node == 0, "got %p\n", text);
7917
7918     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
7919     ok(hr == S_OK, "got 0x%08x\n", hr);
7920
7921     length = 0;
7922     hr = IXMLDOMText_get_length(text, &length);
7923     ok(hr == S_OK, "got 0x%08x\n", hr);
7924     ok(length == 7, "got %d\n", length);
7925
7926     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7927     ok(hr == S_OK, "got 0x%08x\n", hr);
7928     IXMLDOMNode_Release(node);
7929
7930     /* split new text node */
7931     hr = IXMLDOMText_get_length(text, &length);
7932     ok(hr == S_OK, "got 0x%08x\n", hr);
7933
7934     node = (void*)0xdeadbeef;
7935     hr = IXMLDOMText_get_nextSibling(text, &node);
7936     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7937     ok(node == 0, "got %p\n", text);
7938
7939     hr = IXMLDOMText_splitText(text, 0, NULL);
7940     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7941
7942     text2 = (void*)0xdeadbeef;
7943     /* negative offset */
7944     hr = IXMLDOMText_splitText(text, -1, &text2);
7945     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7946     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
7947
7948     text2 = (void*)0xdeadbeef;
7949     /* offset outside data */
7950     hr = IXMLDOMText_splitText(text, length + 1, &text2);
7951     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7952     ok(text2 == 0, "got %p\n", text2);
7953
7954     text2 = (void*)0xdeadbeef;
7955     /* offset outside data */
7956     hr = IXMLDOMText_splitText(text, length, &text2);
7957     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7958     ok(text2 == 0, "got %p\n", text);
7959
7960     text2 = 0;
7961     hr = IXMLDOMText_splitText(text, 4, &text2);
7962     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7963     if (text2) IXMLDOMText_Release(text2);
7964
7965     node = 0;
7966     hr = IXMLDOMText_get_nextSibling(text, &node);
7967     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7968     if (node) IXMLDOMNode_Release(node);
7969
7970     IXMLDOMText_Release(text);
7971     IXMLDOMElement_Release(root);
7972     IXMLDOMCDATASection_Release(cdata);
7973     free_bstrs();
7974 }
7975
7976 static void test_getQualifiedItem(void)
7977 {
7978     IXMLDOMDocument *doc;
7979     IXMLDOMElement *element;
7980     IXMLDOMNode *pr_node, *node;
7981     IXMLDOMNodeList *root_list;
7982     IXMLDOMNamedNodeMap *map;
7983     VARIANT_BOOL b;
7984     BSTR str;
7985     LONG len;
7986     HRESULT hr;
7987
7988     doc = create_document(&IID_IXMLDOMDocument);
7989     if (!doc) return;
7990
7991     str = SysAllocString( szComplete4 );
7992     hr = IXMLDOMDocument_loadXML( doc, str, &b );
7993     ok( hr == S_OK, "loadXML failed\n");
7994     ok( b == VARIANT_TRUE, "failed to load XML string\n");
7995     SysFreeString( str );
7996
7997     hr = IXMLDOMDocument_get_documentElement(doc, &element);
7998     ok( hr == S_OK, "ret %08x\n", hr);
7999
8000     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8001     ok( hr == S_OK, "ret %08x\n", hr);
8002
8003     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8004     ok( hr == S_OK, "ret %08x\n", hr);
8005     IXMLDOMNodeList_Release(root_list);
8006
8007     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8008     ok( hr == S_OK, "ret %08x\n", hr);
8009     IXMLDOMNode_Release(pr_node);
8010
8011     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8012     ok( hr == S_OK, "ret %08x\n", hr);
8013     ok( len == 3, "length %d\n", len);
8014
8015     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8016     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8017
8018     node = (void*)0xdeadbeef;
8019     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8020     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8021     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8022
8023     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8024     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8025
8026     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8027     ok( hr == S_OK, "ret %08x\n", hr);
8028     IXMLDOMNode_Release(node);
8029
8030     IXMLDOMNamedNodeMap_Release( map );
8031     IXMLDOMElement_Release( element );
8032     IXMLDOMDocument_Release( doc );
8033     free_bstrs();
8034 }
8035
8036 static void test_removeQualifiedItem(void)
8037 {
8038     IXMLDOMDocument *doc;
8039     IXMLDOMElement *element;
8040     IXMLDOMNode *pr_node, *node;
8041     IXMLDOMNodeList *root_list;
8042     IXMLDOMNamedNodeMap *map;
8043     VARIANT_BOOL b;
8044     BSTR str;
8045     LONG len;
8046     HRESULT hr;
8047
8048     doc = create_document(&IID_IXMLDOMDocument);
8049     if (!doc) return;
8050
8051     str = SysAllocString( szComplete4 );
8052     hr = IXMLDOMDocument_loadXML( doc, str, &b );
8053     ok( hr == S_OK, "loadXML failed\n");
8054     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8055     SysFreeString( str );
8056
8057     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8058     ok( hr == S_OK, "ret %08x\n", hr);
8059
8060     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8061     ok( hr == S_OK, "ret %08x\n", hr);
8062
8063     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8064     ok( hr == S_OK, "ret %08x\n", hr);
8065     IXMLDOMNodeList_Release(root_list);
8066
8067     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8068     ok( hr == S_OK, "ret %08x\n", hr);
8069     IXMLDOMNode_Release(pr_node);
8070
8071     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8072     ok( hr == S_OK, "ret %08x\n", hr);
8073     ok( len == 3, "length %d\n", len);
8074
8075     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8076     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8077
8078     node = (void*)0xdeadbeef;
8079     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8080     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8081     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8082
8083     /* out pointer is optional */
8084     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8085     ok( hr == S_OK, "ret %08x\n", hr);
8086
8087     /* already removed */
8088     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8089     ok( hr == S_FALSE, "ret %08x\n", hr);
8090
8091     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8092     ok( hr == S_OK, "ret %08x\n", hr);
8093     IXMLDOMNode_Release(node);
8094
8095     IXMLDOMNamedNodeMap_Release( map );
8096     IXMLDOMElement_Release( element );
8097     IXMLDOMDocument_Release( doc );
8098     free_bstrs();
8099 }
8100
8101 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8102 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8103 {
8104     VARIANT_BOOL b;
8105     VARIANT var;
8106     HRESULT hr;
8107
8108     VariantInit(&var);
8109     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8110     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8111     VariantClear(&var);
8112
8113     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8114     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8115     VariantClear(&var);
8116
8117     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8118     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8119
8120     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8121     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8122     VariantClear(&var);
8123 }
8124
8125 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8126 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8127 {
8128     VARIANT_BOOL b;
8129     VARIANT var;
8130
8131     VariantInit(&var);
8132     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8133     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8134     VariantClear(&var);
8135
8136     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8137     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8138     VariantClear(&var);
8139
8140     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8141     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8142
8143     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8144     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8145     VariantClear(&var);
8146 }
8147
8148 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8149 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8150 {
8151     VARIANT var;
8152
8153     VariantInit(&var);
8154     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8155     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8156     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8157     V_VT(&var) = VT_DISPATCH;
8158     V_DISPATCH(&var) = NULL;
8159     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8160     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8161     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8162     VariantClear(&var);
8163 }
8164
8165 #define unset_props(doc) _unset_props(__LINE__, doc)
8166 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8167 {
8168     VARIANT var;
8169
8170     VariantInit(&var);
8171     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8172     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8173     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8174     V_VT(&var) = VT_NULL;
8175     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8176     VariantClear(&var);
8177 }
8178
8179 static void test_get_ownerDocument(void)
8180 {
8181     IXMLDOMDocument *doc1, *doc2, *doc3;
8182     IXMLDOMDocument2 *doc, *doc_owner;
8183     IXMLDOMNode *node;
8184     IXMLDOMSchemaCollection *cache;
8185     VARIANT_BOOL b;
8186     VARIANT var;
8187     BSTR str;
8188
8189     doc = create_document(&IID_IXMLDOMDocument2);
8190     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8191     if (!doc || !cache)
8192     {
8193         if (doc) IXMLDOMDocument2_Release(doc);
8194         if (cache) IXMLDOMSchemaCollection_Release(cache);
8195         return;
8196     }
8197
8198     VariantInit(&var);
8199
8200     str = SysAllocString(szComplete4);
8201     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
8202     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8203     SysFreeString(str);
8204
8205     check_default_props(doc);
8206
8207     /* set properties and check that new instances use them */
8208     set_props(doc, cache);
8209     check_set_props(doc);
8210
8211     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8212     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8213
8214     /* new interface keeps props */
8215     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8216     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8217     check_set_props(doc_owner);
8218     IXMLDOMDocument2_Release(doc_owner);
8219
8220     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8221     IXMLDOMNode_Release(node);
8222
8223     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8224
8225     /* reload */
8226     str = SysAllocString(szComplete4);
8227     ole_check(IXMLDOMDocument2_loadXML(doc, str, &b));
8228     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8229     SysFreeString(str);
8230
8231     /* properties retained even after reload */
8232     check_set_props(doc);
8233
8234     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8235     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8236     IXMLDOMNode_Release(node);
8237
8238     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8239     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8240     check_set_props(doc_owner);
8241
8242     /* changing properties for one instance changes them for all */
8243     unset_props(doc_owner);
8244     check_default_props(doc_owner);
8245     check_default_props(doc);
8246
8247     IXMLDOMSchemaCollection_Release(cache);
8248     IXMLDOMDocument_Release(doc1);
8249     IXMLDOMDocument_Release(doc2);
8250     IXMLDOMDocument_Release(doc3);
8251     IXMLDOMDocument2_Release(doc);
8252     IXMLDOMDocument2_Release(doc_owner);
8253     free_bstrs();
8254 }
8255
8256 static void test_setAttributeNode(void)
8257 {
8258     IXMLDOMDocument *doc, *doc2;
8259     IXMLDOMElement *elem, *elem2;
8260     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8261     VARIANT_BOOL b;
8262     HRESULT hr;
8263     VARIANT v;
8264     BSTR str;
8265     ULONG ref1, ref2;
8266
8267     doc = create_document(&IID_IXMLDOMDocument);
8268     if (!doc) return;
8269
8270     str = SysAllocString( szComplete4 );
8271     hr = IXMLDOMDocument2_loadXML( doc, str, &b );
8272     ok( hr == S_OK, "loadXML failed\n");
8273     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8274     SysFreeString( str );
8275
8276     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8277     ok( hr == S_OK, "got 0x%08x\n", hr);
8278
8279     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8280     ok( hr == S_OK, "got 0x%08x\n", hr);
8281     ok( elem2 != elem, "got same instance\n");
8282
8283     ret_attr = (void*)0xdeadbeef;
8284     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8285     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8286     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8287
8288     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8289     ok( hr == S_OK, "got 0x%08x\n", hr);
8290
8291     ref1 = IXMLDOMElement_AddRef(elem);
8292     IXMLDOMElement_Release(elem);
8293
8294     ret_attr = (void*)0xdeadbeef;
8295     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8296     ok( hr == S_OK, "got 0x%08x\n", hr);
8297     ok( ret_attr == NULL, "got %p\n", ret_attr);
8298
8299     /* no reference added */
8300     ref2 = IXMLDOMElement_AddRef(elem);
8301     IXMLDOMElement_Release(elem);
8302     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8303
8304     EXPECT_CHILDREN(elem);
8305     EXPECT_CHILDREN(elem2);
8306
8307     IXMLDOMElement_Release(elem2);
8308
8309     attr2 = NULL;
8310     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8311     ok( hr == S_OK, "got 0x%08x\n", hr);
8312     ok( attr2 != attr, "got same instance %p\n", attr2);
8313     IXMLDOMAttribute_Release(attr2);
8314
8315     /* try to add it another time */
8316     ret_attr = (void*)0xdeadbeef;
8317     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8318     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8319     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8320
8321     IXMLDOMElement_Release(elem);
8322
8323     /* initially used element is released, attribute still 'has' a container */
8324     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8325     ok( hr == S_OK, "got 0x%08x\n", hr);
8326     ret_attr = (void*)0xdeadbeef;
8327     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8328     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8329     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8330     IXMLDOMElement_Release(elem);
8331
8332     /* add attribute already attached to another document */
8333     doc2 = create_document(&IID_IXMLDOMDocument);
8334
8335     str = SysAllocString( szComplete4 );
8336     hr = IXMLDOMDocument_loadXML( doc2, str, &b );
8337     ok( hr == S_OK, "loadXML failed\n");
8338     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8339     SysFreeString( str );
8340
8341     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8342     ok( hr == S_OK, "got 0x%08x\n", hr);
8343     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8344     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8345     IXMLDOMElement_Release(elem);
8346
8347     IXMLDOMAttribute_Release(attr);
8348
8349     /* create element, add attribute, see if it's copied or linked */
8350     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8351     ok( hr == S_OK, "got 0x%08x\n", hr);
8352
8353     attr = NULL;
8354     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8355     ok(hr == S_OK, "got 0x%08x\n", hr);
8356     ok(attr != NULL, "got %p\n", attr);
8357
8358     ref1 = IXMLDOMAttribute_AddRef(attr);
8359     IXMLDOMAttribute_Release(attr);
8360
8361     V_VT(&v) = VT_BSTR;
8362     V_BSTR(&v) = _bstr_("attrvalue1");
8363     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8364     ok( hr == S_OK, "got 0x%08x\n", hr);
8365
8366     str = NULL;
8367     hr = IXMLDOMAttribute_get_xml(attr, &str);
8368     ok( hr == S_OK, "got 0x%08x\n", hr);
8369     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8370         "got %s\n", wine_dbgstr_w(str));
8371     SysFreeString(str);
8372
8373     ret_attr = (void*)0xdeadbeef;
8374     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8375     ok(hr == S_OK, "got 0x%08x\n", hr);
8376     ok(ret_attr == NULL, "got %p\n", ret_attr);
8377
8378     /* attribute reference increased */
8379     ref2 = IXMLDOMAttribute_AddRef(attr);
8380     IXMLDOMAttribute_Release(attr);
8381     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8382
8383     hr = IXMLDOMElement_get_xml(elem, &str);
8384     ok( hr == S_OK, "got 0x%08x\n", hr);
8385     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8386         "got %s\n", wine_dbgstr_w(str));
8387     SysFreeString(str);
8388
8389     V_VT(&v) = VT_BSTR;
8390     V_BSTR(&v) = _bstr_("attrvalue2");
8391     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8392     ok( hr == S_OK, "got 0x%08x\n", hr);
8393
8394     hr = IXMLDOMElement_get_xml(elem, &str);
8395     ok( hr == S_OK, "got 0x%08x\n", hr);
8396     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8397         "got %s\n", wine_dbgstr_w(str));
8398     SysFreeString(str);
8399
8400     IXMLDOMElement_Release(elem);
8401     IXMLDOMAttribute_Release(attr);
8402     IXMLDOMDocument_Release(doc2);
8403     IXMLDOMDocument_Release(doc);
8404 }
8405
8406 static void test_put_dataType(void)
8407 {
8408     IXMLDOMCDATASection *cdata;
8409     IXMLDOMDocument *doc;
8410     VARIANT_BOOL b;
8411     HRESULT hr;
8412     BSTR str;
8413
8414     doc = create_document(&IID_IXMLDOMDocument);
8415     if (!doc) return;
8416
8417     str = SysAllocString( szComplete4 );
8418     hr = IXMLDOMDocument_loadXML( doc, str, &b );
8419     ok( hr == S_OK, "loadXML failed\n");
8420     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8421     SysFreeString( str );
8422
8423     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
8424     ok( hr == S_OK, "got 0x%08x\n", hr);
8425     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
8426     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8427     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
8428     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8429     IXMLDOMCDATASection_Release(cdata);
8430
8431     IXMLDOMDocument_Release(doc);
8432     free_bstrs();
8433 }
8434
8435 static void test_createNode(void)
8436 {
8437     IXMLDOMDocument *doc;
8438     IXMLDOMElement *elem;
8439     IXMLDOMNode *node;
8440     VARIANT v, var;
8441     BSTR prefix, str;
8442     HRESULT hr;
8443     ULONG ref;
8444
8445     doc = create_document(&IID_IXMLDOMDocument);
8446     if (!doc) return;
8447
8448     EXPECT_REF(doc, 1);
8449
8450     /* reference count tests */
8451     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8452     ok( hr == S_OK, "got 0x%08x\n", hr);
8453
8454     /* initial reference is 2 */
8455 todo_wine {
8456     EXPECT_REF(elem, 2);
8457     ref = IXMLDOMElement_Release(elem);
8458     ok(ref == 1, "got %d\n", ref);
8459     /* it's released already, attempt to release now will crash it */
8460 }
8461
8462     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8463     ok( hr == S_OK, "got 0x%08x\n", hr);
8464     todo_wine EXPECT_REF(elem, 2);
8465     IXMLDOMDocument_Release(doc);
8466     todo_wine EXPECT_REF(elem, 2);
8467     IXMLDOMElement_Release(elem);
8468
8469     doc = create_document(&IID_IXMLDOMDocument);
8470
8471     /* NODE_ELEMENT nodes */
8472     /* 1. specified namespace */
8473     V_VT(&v) = VT_I4;
8474     V_I4(&v) = NODE_ELEMENT;
8475
8476     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8477     ok( hr == S_OK, "got 0x%08x\n", hr);
8478     prefix = NULL;
8479     hr = IXMLDOMNode_get_prefix(node, &prefix);
8480     ok( hr == S_OK, "got 0x%08x\n", hr);
8481     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8482     SysFreeString(prefix);
8483     IXMLDOMNode_Release(node);
8484
8485     /* 2. default namespace */
8486     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8487     ok( hr == S_OK, "got 0x%08x\n", hr);
8488     prefix = (void*)0xdeadbeef;
8489     hr = IXMLDOMNode_get_prefix(node, &prefix);
8490     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8491     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8492     /* check dump */
8493     hr = IXMLDOMNode_get_xml(node, &str);
8494     ok( hr == S_OK, "got 0x%08x\n", hr);
8495     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8496         "got %s\n", wine_dbgstr_w(str));
8497     SysFreeString(str);
8498
8499     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8500     ok( hr == S_OK, "got 0x%08x\n", hr);
8501
8502     V_VT(&var) = VT_BSTR;
8503     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8504     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8505     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8506
8507     str = NULL;
8508     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8509     ok( hr == S_OK, "got 0x%08x\n", hr);
8510     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8511     SysFreeString(str);
8512
8513     IXMLDOMElement_Release(elem);
8514     IXMLDOMNode_Release(node);
8515
8516     IXMLDOMDocument_Release(doc);
8517     free_bstrs();
8518 }
8519
8520 static void test_get_prefix(void)
8521 {
8522     IXMLDOMDocumentFragment *fragment;
8523     IXMLDOMCDATASection *cdata;
8524     IXMLDOMElement *element;
8525     IXMLDOMComment *comment;
8526     IXMLDOMDocument *doc;
8527     HRESULT hr;
8528     BSTR str;
8529
8530     doc = create_document(&IID_IXMLDOMDocument);
8531     if (!doc) return;
8532
8533     /* nodes that can't support prefix */
8534     /* 1. document */
8535     str = (void*)0xdeadbeef;
8536     hr = IXMLDOMDocument_get_prefix(doc, &str);
8537     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8538     ok( str == 0, "got %p\n", str);
8539
8540     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8541     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8542
8543     /* 2. cdata */
8544     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8545     ok(hr == S_OK, "got %08x\n", hr );
8546
8547     str = (void*)0xdeadbeef;
8548     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8549     ok(hr == S_FALSE, "got %08x\n", hr);
8550     ok( str == 0, "got %p\n", str);
8551
8552     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8553     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8554     IXMLDOMCDATASection_Release(cdata);
8555
8556     /* 3. comment */
8557     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8558     ok(hr == S_OK, "got %08x\n", hr );
8559
8560     str = (void*)0xdeadbeef;
8561     hr = IXMLDOMComment_get_prefix(comment, &str);
8562     ok(hr == S_FALSE, "got %08x\n", hr);
8563     ok( str == 0, "got %p\n", str);
8564
8565     hr = IXMLDOMComment_get_prefix(comment, NULL);
8566     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8567     IXMLDOMComment_Release(comment);
8568
8569     /* 4. fragment */
8570     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8571     ok(hr == S_OK, "got %08x\n", hr );
8572
8573     str = (void*)0xdeadbeef;
8574     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8575     ok(hr == S_FALSE, "got %08x\n", hr);
8576     ok( str == 0, "got %p\n", str);
8577
8578     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8579     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8580     IXMLDOMDocumentFragment_Release(fragment);
8581
8582     /* no prefix */
8583     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8584     ok( hr == S_OK, "got 0x%08x\n", hr);
8585
8586     hr = IXMLDOMElement_get_prefix(element, NULL);
8587     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8588
8589     str = (void*)0xdeadbeef;
8590     hr = IXMLDOMElement_get_prefix(element, &str);
8591     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8592     ok( str == 0, "got %p\n", str);
8593
8594     IXMLDOMElement_Release(element);
8595
8596     /* with prefix */
8597     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8598     ok( hr == S_OK, "got 0x%08x\n", hr);
8599
8600     str = (void*)0xdeadbeef;
8601     hr = IXMLDOMElement_get_prefix(element, &str);
8602     ok( hr == S_OK, "got 0x%08x\n", hr);
8603     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8604     SysFreeString(str);
8605
8606     str = (void*)0xdeadbeef;
8607     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8608     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8609     ok( str == 0, "got %p\n", str);
8610
8611     IXMLDOMElement_Release(element);
8612
8613     IXMLDOMDocument_Release(doc);
8614     free_bstrs();
8615 }
8616
8617 static void test_selectSingleNode(void)
8618 {
8619     IXMLDOMDocument *doc;
8620     IXMLDOMNodeList *list;
8621     IXMLDOMNode *node;
8622     VARIANT_BOOL b;
8623     HRESULT hr;
8624     LONG len;
8625     BSTR str;
8626
8627     doc = create_document(&IID_IXMLDOMDocument);
8628     if (!doc) return;
8629
8630     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8631     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8632
8633     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8634     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8635
8636     str = SysAllocString( szComplete4 );
8637     hr = IXMLDOMDocument_loadXML( doc, str, &b );
8638     ok( hr == S_OK, "loadXML failed\n");
8639     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8640     SysFreeString( str );
8641
8642     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8643     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8644
8645     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8646     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8647
8648     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8649     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8650
8651     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8652     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8653
8654     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8655     ok(hr == S_OK, "got 0x%08x\n", hr);
8656     IXMLDOMNode_Release(node);
8657
8658     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8659     ok(hr == S_OK, "got 0x%08x\n", hr);
8660     IXMLDOMNodeList_Release(list);
8661
8662     list = (void*)0xdeadbeef;
8663     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8664     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8665     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8666
8667     node = (void*)0xdeadbeef;
8668     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8669     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8670     ok(node == 0, "got %p\n", node);
8671
8672     list = (void*)0xdeadbeef;
8673     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8674     ok(hr == S_OK, "got 0x%08x\n", hr);
8675     len = 1;
8676     hr = IXMLDOMNodeList_get_length(list, &len);
8677     ok(hr == S_OK, "got 0x%08x\n", hr);
8678     ok(len == 0, "got %d\n", len);
8679     IXMLDOMNodeList_Release(list);
8680
8681     IXMLDOMDocument_Release(doc);
8682     free_bstrs();
8683 }
8684
8685 static void test_events(void)
8686 {
8687     IConnectionPointContainer *conn;
8688     IConnectionPoint *point;
8689     IXMLDOMDocument *doc;
8690     HRESULT hr;
8691     VARIANT v;
8692     IDispatch *event;
8693
8694     doc = create_document(&IID_IXMLDOMDocument);
8695     if (!doc) return;
8696
8697     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8698     ok(hr == S_OK, "got 0x%08x\n", hr);
8699
8700     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8701     ok(hr == S_OK, "got 0x%08x\n", hr);
8702     IConnectionPoint_Release(point);
8703     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8704     ok(hr == S_OK, "got 0x%08x\n", hr);
8705     IConnectionPoint_Release(point);
8706     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8707     ok(hr == S_OK, "got 0x%08x\n", hr);
8708     IConnectionPoint_Release(point);
8709
8710     IConnectionPointContainer_Release(conn);
8711
8712     /* ready state callback */
8713     VariantInit(&v);
8714     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8715     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8716
8717     event = create_dispevent();
8718     V_VT(&v) = VT_UNKNOWN;
8719     V_UNKNOWN(&v) = (IUnknown*)event;
8720
8721     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8722     ok(hr == S_OK, "got 0x%08x\n", hr);
8723     EXPECT_REF(event, 2);
8724
8725     V_VT(&v) = VT_DISPATCH;
8726     V_DISPATCH(&v) = event;
8727
8728     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8729     ok(hr == S_OK, "got 0x%08x\n", hr);
8730     EXPECT_REF(event, 2);
8731
8732     /* VT_NULL doesn't reset event handler */
8733     V_VT(&v) = VT_NULL;
8734     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8735     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8736     EXPECT_REF(event, 2);
8737
8738     V_VT(&v) = VT_DISPATCH;
8739     V_DISPATCH(&v) = NULL;
8740
8741     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8742     ok(hr == S_OK, "got 0x%08x\n", hr);
8743     EXPECT_REF(event, 1);
8744
8745     V_VT(&v) = VT_UNKNOWN;
8746     V_DISPATCH(&v) = NULL;
8747     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8748     ok(hr == S_OK, "got 0x%08x\n", hr);
8749
8750     IDispatch_Release(event);
8751
8752     IXMLDOMDocument_Release(doc);
8753 }
8754
8755 static void test_createProcessingInstruction(void)
8756 {
8757     static const WCHAR bodyW[] = {'t','e','s','t',0};
8758     IXMLDOMProcessingInstruction *pi;
8759     IXMLDOMDocument *doc;
8760     WCHAR buff[10];
8761     HRESULT hr;
8762
8763     doc = create_document(&IID_IXMLDOMDocument);
8764     if (!doc) return;
8765
8766     /* test for BSTR handling, pass broken BSTR */
8767     memcpy(&buff[2], bodyW, sizeof(bodyW));
8768     /* just a big length */
8769     *(DWORD*)buff = 0xf0f0;
8770     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
8771     ok(hr == S_OK, "got 0x%08x\n", hr);
8772
8773     IXMLDOMProcessingInstruction_Release(pi);
8774     IXMLDOMDocument_Release(doc);
8775 }
8776
8777 static void test_put_nodeTypedValue(void)
8778 {
8779     IXMLDOMDocument *doc;
8780     IXMLDOMElement *elem;
8781     VARIANT type;
8782     HRESULT hr;
8783
8784     doc = create_document(&IID_IXMLDOMDocument);
8785     if (!doc) return;
8786
8787     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
8788     ok(hr == S_OK, "got 0x%08x\n", hr);
8789
8790     V_VT(&type) = VT_EMPTY;
8791     hr = IXMLDOMElement_get_dataType(elem, &type);
8792     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8793     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8794
8795     /* set typed value for untyped node */
8796     V_VT(&type) = VT_I1;
8797     V_I1(&type) = 1;
8798     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
8799     ok(hr == S_OK, "got 0x%08x\n", hr);
8800
8801     V_VT(&type) = VT_EMPTY;
8802     hr = IXMLDOMElement_get_dataType(elem, &type);
8803     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8804     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8805
8806     /* no type info stored */
8807     V_VT(&type) = VT_EMPTY;
8808     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
8809     ok(hr == S_OK, "got 0x%08x\n", hr);
8810     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
8811     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
8812        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
8813     VariantClear(&type);
8814
8815     IXMLDOMElement_Release(elem);
8816     IXMLDOMDocument_Release(doc);
8817     free_bstrs();
8818 }
8819
8820 static void test_get_xml(void)
8821 {
8822     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
8823     static const char fooA[] = "<foo/>";
8824     IXMLDOMProcessingInstruction *pi;
8825     IXMLDOMNode *first;
8826     IXMLDOMElement *elem = NULL;
8827     IXMLDOMDocument *doc;
8828     VARIANT_BOOL b;
8829     VARIANT v;
8830     BSTR xml;
8831     HRESULT hr;
8832
8833     doc = create_document(&IID_IXMLDOMDocument);
8834     if (!doc) return;
8835
8836     b = VARIANT_TRUE;
8837     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8838     ok(hr == S_OK, "got 0x%08x\n", hr);
8839     ok( b == VARIANT_TRUE, "got %d\n", b);
8840
8841     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
8842                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
8843     ok(hr == S_OK, "got 0x%08x\n", hr);
8844
8845     hr = IXMLDOMDocument_get_firstChild(doc, &first);
8846     ok(hr == S_OK, "got 0x%08x\n", hr);
8847
8848     V_UNKNOWN(&v) = (IUnknown*)first;
8849     V_VT(&v) = VT_UNKNOWN;
8850
8851     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
8852     ok(hr == S_OK, "got 0x%08x\n", hr);
8853
8854     IXMLDOMProcessingInstruction_Release(pi);
8855     IXMLDOMNode_Release(first);
8856
8857     hr = IXMLDOMDocument_get_xml(doc, &xml);
8858     ok(hr == S_OK, "got 0x%08x\n", hr);
8859
8860     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
8861         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
8862     SysFreeString(xml);
8863
8864     IXMLDOMDocument_Release(doc);
8865
8866     doc = create_document(&IID_IXMLDOMDocument);
8867
8868     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
8869     ok(hr == S_OK, "got 0x%08x\n", hr);
8870
8871     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
8872     ok(hr == S_OK, "got 0x%08x\n", hr);
8873
8874     hr = IXMLDOMDocument_get_xml(doc, &xml);
8875     ok(hr == S_OK, "got 0x%08x\n", hr);
8876
8877     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
8878         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
8879     SysFreeString(xml);
8880
8881     IXMLDOMElement_Release(elem);
8882     IXMLDOMDocument_Release(doc);
8883
8884     free_bstrs();
8885 }
8886
8887 static void test_xsltemplate(void)
8888 {
8889     IXSLTemplate *template;
8890     IXSLProcessor *processor;
8891     IXMLDOMDocument *doc, *doc2;
8892     IStream *stream;
8893     VARIANT_BOOL b;
8894     HRESULT hr;
8895     ULONG ref1, ref2;
8896     VARIANT v;
8897
8898     template = create_xsltemplate(&IID_IXSLTemplate);
8899     if (!template) return;
8900
8901     /* works as reset */
8902     hr = IXSLTemplate_putref_stylesheet(template, NULL);
8903     ok(hr == S_OK, "got 0x%08x\n", hr);
8904
8905     doc = create_document(&IID_IXMLDOMDocument);
8906
8907     b = VARIANT_TRUE;
8908     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8909     ok(hr == S_OK, "got 0x%08x\n", hr);
8910     ok( b == VARIANT_TRUE, "got %d\n", b);
8911
8912     /* putref with non-xsl document */
8913     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8914     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8915
8916     b = VARIANT_TRUE;
8917     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8918     ok(hr == S_OK, "got 0x%08x\n", hr);
8919     ok( b == VARIANT_TRUE, "got %d\n", b);
8920
8921     /* not a freethreaded document */
8922     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8923     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8924
8925     IXMLDOMDocument_Release(doc);
8926
8927     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
8928     if (hr != S_OK)
8929     {
8930         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
8931         IXSLTemplate_Release(template);
8932         return;
8933     }
8934
8935     b = VARIANT_TRUE;
8936     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8937     ok(hr == S_OK, "got 0x%08x\n", hr);
8938     ok( b == VARIANT_TRUE, "got %d\n", b);
8939
8940     /* freethreaded document */
8941     ref1 = IXMLDOMDocument_AddRef(doc);
8942     IXMLDOMDocument_Release(doc);
8943     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8944     ok(hr == S_OK, "got 0x%08x\n", hr);
8945     ref2 = IXMLDOMDocument_AddRef(doc);
8946     IXMLDOMDocument_Release(doc);
8947     ok(ref2 > ref1, "got %d\n", ref2);
8948
8949     /* processor */
8950     hr = IXSLTemplate_createProcessor(template, NULL);
8951     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8952
8953     EXPECT_REF(template, 1);
8954     hr = IXSLTemplate_createProcessor(template, &processor);
8955     ok(hr == S_OK, "got 0x%08x\n", hr);
8956     EXPECT_REF(template, 2);
8957
8958     /* input no set yet */
8959     V_VT(&v) = VT_BSTR;
8960     V_BSTR(&v) = NULL;
8961     hr = IXSLProcessor_get_input(processor, &v);
8962 todo_wine {
8963     ok(hr == S_OK, "got 0x%08x\n", hr);
8964     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
8965 }
8966
8967     hr = IXSLProcessor_get_output(processor, NULL);
8968     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8969
8970     /* reset before it was set */
8971     V_VT(&v) = VT_EMPTY;
8972     hr = IXSLProcessor_put_output(processor, v);
8973     ok(hr == S_OK, "got 0x%08x\n", hr);
8974
8975     CreateStreamOnHGlobal(NULL, TRUE, &stream);
8976     EXPECT_REF(stream, 1);
8977
8978     V_VT(&v) = VT_UNKNOWN;
8979     V_UNKNOWN(&v) = (IUnknown*)stream;
8980     hr = IXSLProcessor_put_output(processor, v);
8981     ok(hr == S_OK, "got 0x%08x\n", hr);
8982
8983     /* it seems processor grabs 2 references */
8984     todo_wine EXPECT_REF(stream, 3);
8985
8986     V_VT(&v) = VT_EMPTY;
8987     hr = IXSLProcessor_get_output(processor, &v);
8988     ok(hr == S_OK, "got 0x%08x\n", hr);
8989     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
8990     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
8991
8992     todo_wine EXPECT_REF(stream, 4);
8993     VariantClear(&v);
8994
8995     hr = IXSLProcessor_transform(processor, NULL);
8996     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8997
8998     /* reset and check stream refcount */
8999     V_VT(&v) = VT_EMPTY;
9000     hr = IXSLProcessor_put_output(processor, v);
9001     ok(hr == S_OK, "got 0x%08x\n", hr);
9002
9003     EXPECT_REF(stream, 1);
9004
9005     IStream_Release(stream);
9006
9007     /* no output interface set, check output */
9008     doc2 = create_document(&IID_IXMLDOMDocument);
9009
9010     b = VARIANT_TRUE;
9011     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9012     ok(hr == S_OK, "got 0x%08x\n", hr);
9013     ok( b == VARIANT_TRUE, "got %d\n", b);
9014
9015     V_VT(&v) = VT_UNKNOWN;
9016     V_UNKNOWN(&v) = (IUnknown*)doc2;
9017     hr = IXSLProcessor_put_input(processor, v);
9018     ok(hr == S_OK, "got 0x%08x\n", hr);
9019
9020     hr = IXSLProcessor_transform(processor, &b);
9021     ok(hr == S_OK, "got 0x%08x\n", hr);
9022
9023     V_VT(&v) = VT_EMPTY;
9024     hr = IXSLProcessor_get_output(processor, &v);
9025     ok(hr == S_OK, "got 0x%08x\n", hr);
9026     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9027     /* we currently output one '\n' instead of empty string */
9028     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9029     IXMLDOMDocument_Release(doc2);
9030     VariantClear(&v);
9031
9032     IXSLProcessor_Release(processor);
9033
9034     /* drop reference */
9035     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9036     ok(hr == S_OK, "got 0x%08x\n", hr);
9037     ref2 = IXMLDOMDocument_AddRef(doc);
9038     IXMLDOMDocument_Release(doc);
9039     ok(ref2 == ref1, "got %d\n", ref2);
9040
9041     IXMLDOMDocument_Release(doc);
9042     IXSLTemplate_Release(template);
9043     free_bstrs();
9044 }
9045
9046 static void test_insertBefore(void)
9047 {
9048     IXMLDOMDocument *doc, *doc2;
9049     IXMLDOMAttribute *attr;
9050     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9051     IXMLDOMNode *node, *newnode;
9052     HRESULT hr;
9053     VARIANT v;
9054     BSTR p;
9055
9056     doc = create_document(&IID_IXMLDOMDocument);
9057
9058     /* insertBefore behaviour for attribute node */
9059     V_VT(&v) = VT_I4;
9060     V_I4(&v) = NODE_ATTRIBUTE;
9061
9062     attr = NULL;
9063     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9064     ok(hr == S_OK, "got 0x%08x\n", hr);
9065     ok(attr != NULL, "got %p\n", attr);
9066
9067     /* attribute to attribute */
9068     V_VT(&v) = VT_I4;
9069     V_I4(&v) = NODE_ATTRIBUTE;
9070     newnode = NULL;
9071     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9072     ok(hr == S_OK, "got 0x%08x\n", hr);
9073     ok(newnode != NULL, "got %p\n", newnode);
9074
9075     V_VT(&v) = VT_NULL;
9076     node = (void*)0xdeadbeef;
9077     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9078     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9079     ok(node == NULL, "got %p\n", node);
9080
9081     V_VT(&v) = VT_UNKNOWN;
9082     V_UNKNOWN(&v) = (IUnknown*)attr;
9083     node = (void*)0xdeadbeef;
9084     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9085     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9086     ok(node == NULL, "got %p\n", node);
9087     IXMLDOMNode_Release(newnode);
9088
9089     /* cdata to attribute */
9090     V_VT(&v) = VT_I4;
9091     V_I4(&v) = NODE_CDATA_SECTION;
9092     newnode = NULL;
9093     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9094     ok(hr == S_OK, "got 0x%08x\n", hr);
9095     ok(newnode != NULL, "got %p\n", newnode);
9096
9097     V_VT(&v) = VT_NULL;
9098     node = (void*)0xdeadbeef;
9099     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9100     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9101     ok(node == NULL, "got %p\n", node);
9102     IXMLDOMNode_Release(newnode);
9103
9104     /* comment to attribute */
9105     V_VT(&v) = VT_I4;
9106     V_I4(&v) = NODE_COMMENT;
9107     newnode = NULL;
9108     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9109     ok(hr == S_OK, "got 0x%08x\n", hr);
9110     ok(newnode != NULL, "got %p\n", newnode);
9111
9112     V_VT(&v) = VT_NULL;
9113     node = (void*)0xdeadbeef;
9114     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9115     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9116     ok(node == NULL, "got %p\n", node);
9117     IXMLDOMNode_Release(newnode);
9118
9119     /* element to attribute */
9120     V_VT(&v) = VT_I4;
9121     V_I4(&v) = NODE_ELEMENT;
9122     newnode = NULL;
9123     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9124     ok(hr == S_OK, "got 0x%08x\n", hr);
9125     ok(newnode != NULL, "got %p\n", newnode);
9126
9127     V_VT(&v) = VT_NULL;
9128     node = (void*)0xdeadbeef;
9129     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9130     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9131     ok(node == NULL, "got %p\n", node);
9132     IXMLDOMNode_Release(newnode);
9133
9134     /* pi to attribute */
9135     V_VT(&v) = VT_I4;
9136     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9137     newnode = NULL;
9138     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9139     ok(hr == S_OK, "got 0x%08x\n", hr);
9140     ok(newnode != NULL, "got %p\n", newnode);
9141
9142     V_VT(&v) = VT_NULL;
9143     node = (void*)0xdeadbeef;
9144     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9145     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9146     ok(node == NULL, "got %p\n", node);
9147     IXMLDOMNode_Release(newnode);
9148     IXMLDOMAttribute_Release(attr);
9149
9150     /* insertBefore for elements */
9151     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9152     ok(hr == S_OK, "got 0x%08x\n", hr);
9153
9154     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9155     ok(hr == S_OK, "got 0x%08x\n", hr);
9156
9157     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9158     ok(hr == S_OK, "got 0x%08x\n", hr);
9159
9160     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9161     ok(hr == S_OK, "got 0x%08x\n", hr);
9162
9163     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9164     ok(hr == S_OK, "got 0x%08x\n", hr);
9165
9166     EXPECT_NO_CHILDREN(elem1);
9167     EXPECT_NO_CHILDREN(elem2);
9168     EXPECT_NO_CHILDREN(elem3);
9169
9170     todo_wine EXPECT_REF(elem2, 2);
9171
9172     V_VT(&v) = VT_DISPATCH;
9173     V_DISPATCH(&v) = NULL;
9174     node = NULL;
9175     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9176     ok(hr == S_OK, "got 0x%08x\n", hr);
9177     ok(node == (void*)elem4, "got %p\n", node);
9178
9179     EXPECT_CHILDREN(elem1);
9180     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9181     EXPECT_HR(hr, S_OK);
9182     IXMLDOMElement_Release(elem4);
9183
9184     EXPECT_NO_CHILDREN(elem1);
9185
9186     V_VT(&v) = VT_NULL;
9187     node = NULL;
9188     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9189     ok(hr == S_OK, "got 0x%08x\n", hr);
9190     ok(node == (void*)elem2, "got %p\n", node);
9191
9192     EXPECT_CHILDREN(elem1);
9193     todo_wine EXPECT_REF(elem2, 3);
9194     IXMLDOMNode_Release(node);
9195
9196     /* again for already linked node */
9197     V_VT(&v) = VT_NULL;
9198     node = NULL;
9199     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9200     ok(hr == S_OK, "got 0x%08x\n", hr);
9201     ok(node == (void*)elem2, "got %p\n", node);
9202
9203     EXPECT_CHILDREN(elem1);
9204
9205     /* increments each time */
9206     todo_wine EXPECT_REF(elem2, 3);
9207     IXMLDOMNode_Release(node);
9208
9209     /* try to add to another element */
9210     V_VT(&v) = VT_NULL;
9211     node = (void*)0xdeadbeef;
9212     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9213     ok(hr == S_OK, "got 0x%08x\n", hr);
9214     ok(node == (void*)elem2, "got %p\n", node);
9215
9216     EXPECT_CHILDREN(elem3);
9217     EXPECT_NO_CHILDREN(elem1);
9218
9219     IXMLDOMNode_Release(node);
9220
9221     /* cross document case - try to add as child to a node created with other doc */
9222     doc2 = create_document(&IID_IXMLDOMDocument);
9223
9224     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9225     ok(hr == S_OK, "got 0x%08x\n", hr);
9226     todo_wine EXPECT_REF(elem4, 2);
9227
9228     /* same name, another instance */
9229     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9230     ok(hr == S_OK, "got 0x%08x\n", hr);
9231     todo_wine EXPECT_REF(elem5, 2);
9232
9233     todo_wine EXPECT_REF(elem3, 2);
9234     V_VT(&v) = VT_NULL;
9235     node = NULL;
9236     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9237     ok(hr == S_OK, "got 0x%08x\n", hr);
9238     ok(node == (void*)elem4, "got %p\n", node);
9239     todo_wine EXPECT_REF(elem4, 3);
9240     todo_wine EXPECT_REF(elem3, 2);
9241     IXMLDOMNode_Release(node);
9242
9243     V_VT(&v) = VT_NULL;
9244     node = NULL;
9245     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9246     ok(hr == S_OK, "got 0x%08x\n", hr);
9247     ok(node == (void*)elem5, "got %p\n", node);
9248     todo_wine EXPECT_REF(elem4, 2);
9249     todo_wine EXPECT_REF(elem5, 3);
9250     IXMLDOMNode_Release(node);
9251
9252     IXMLDOMDocument_Release(doc2);
9253
9254     IXMLDOMElement_Release(elem1);
9255     IXMLDOMElement_Release(elem2);
9256     IXMLDOMElement_Release(elem3);
9257     IXMLDOMElement_Release(elem4);
9258     IXMLDOMElement_Release(elem5);
9259
9260     /* elements with same default namespace */
9261     V_VT(&v) = VT_I4;
9262     V_I4(&v) = NODE_ELEMENT;
9263     elem1 = NULL;
9264     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9265     ok(hr == S_OK, "got 0x%08x\n", hr);
9266     ok(elem1 != NULL, "got %p\n", elem1);
9267
9268     V_VT(&v) = VT_I4;
9269     V_I4(&v) = NODE_ELEMENT;
9270     elem2 = NULL;
9271     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9272     ok(hr == S_OK, "got 0x%08x\n", hr);
9273     ok(elem2 != NULL, "got %p\n", elem2);
9274
9275     /* check contents so far */
9276     p = NULL;
9277     hr = IXMLDOMElement_get_xml(elem1, &p);
9278     ok(hr == S_OK, "got 0x%08x\n", hr);
9279     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9280     SysFreeString(p);
9281
9282     p = NULL;
9283     hr = IXMLDOMElement_get_xml(elem2, &p);
9284     ok(hr == S_OK, "got 0x%08x\n", hr);
9285     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9286     SysFreeString(p);
9287
9288     V_VT(&v) = VT_NULL;
9289     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9290     ok(hr == S_OK, "got 0x%08x\n", hr);
9291
9292     /* get_xml depends on context, for top node it omits child namespace attribute,
9293        but at child level it's still returned */
9294     p = NULL;
9295     hr = IXMLDOMElement_get_xml(elem1, &p);
9296     ok(hr == S_OK, "got 0x%08x\n", hr);
9297     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9298         "got %s\n", wine_dbgstr_w(p));
9299     SysFreeString(p);
9300
9301     p = NULL;
9302     hr = IXMLDOMElement_get_xml(elem2, &p);
9303     ok(hr == S_OK, "got 0x%08x\n", hr);
9304     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9305     SysFreeString(p);
9306
9307     IXMLDOMElement_Release(elem1);
9308     IXMLDOMElement_Release(elem2);
9309
9310     /* child without default namespace added to node with default namespace */
9311     V_VT(&v) = VT_I4;
9312     V_I4(&v) = NODE_ELEMENT;
9313     elem1 = NULL;
9314     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9315     ok(hr == S_OK, "got 0x%08x\n", hr);
9316     ok(elem1 != NULL, "got %p\n", elem1);
9317
9318     V_VT(&v) = VT_I4;
9319     V_I4(&v) = NODE_ELEMENT;
9320     elem2 = NULL;
9321     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9322     ok(hr == S_OK, "got 0x%08x\n", hr);
9323     ok(elem2 != NULL, "got %p\n", elem2);
9324
9325     EXPECT_REF(elem2, 1);
9326     V_VT(&v) = VT_NULL;
9327     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9328     ok(hr == S_OK, "got 0x%08x\n", hr);
9329     EXPECT_REF(elem2, 1);
9330
9331     p = NULL;
9332     hr = IXMLDOMElement_get_xml(elem2, &p);
9333     ok(hr == S_OK, "got 0x%08x\n", hr);
9334     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9335     SysFreeString(p);
9336
9337     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9338     ok(hr == S_OK, "got 0x%08x\n", hr);
9339
9340     p = NULL;
9341     hr = IXMLDOMElement_get_xml(elem2, &p);
9342     ok(hr == S_OK, "got 0x%08x\n", hr);
9343     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9344     SysFreeString(p);
9345
9346     IXMLDOMElement_Release(elem1);
9347     IXMLDOMElement_Release(elem2);
9348     IXMLDOMDocument_Release(doc);
9349 }
9350
9351 static void test_appendChild(void)
9352 {
9353     IXMLDOMDocument *doc, *doc2;
9354     IXMLDOMElement *elem, *elem2;
9355     HRESULT hr;
9356
9357     doc = create_document(&IID_IXMLDOMDocument);
9358     doc2 = create_document(&IID_IXMLDOMDocument);
9359
9360     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9361     ok(hr == S_OK, "got 0x%08x\n", hr);
9362
9363     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9364     ok(hr == S_OK, "got 0x%08x\n", hr);
9365
9366     EXPECT_REF(doc, 1);
9367     todo_wine EXPECT_REF(elem, 2);
9368     EXPECT_REF(doc2, 1);
9369     todo_wine EXPECT_REF(elem2, 2);
9370     EXPECT_NO_CHILDREN(doc);
9371     EXPECT_NO_CHILDREN(doc2);
9372
9373     /* append from another document */
9374     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9375     ok(hr == S_OK, "got 0x%08x\n", hr);
9376
9377     EXPECT_REF(doc, 1);
9378     todo_wine EXPECT_REF(elem, 2);
9379     EXPECT_REF(doc2, 1);
9380     todo_wine EXPECT_REF(elem2, 2);
9381     EXPECT_NO_CHILDREN(doc);
9382     EXPECT_CHILDREN(doc2);
9383
9384     IXMLDOMElement_Release(elem);
9385     IXMLDOMElement_Release(elem2);
9386     IXMLDOMDocument_Release(doc);
9387     IXMLDOMDocument_Release(doc2);
9388 }
9389
9390 static void test_get_doctype(void)
9391 {
9392     IXMLDOMDocumentType *doctype;
9393     IXMLDOMDocument *doc;
9394     HRESULT hr;
9395
9396     doc = create_document(&IID_IXMLDOMDocument);
9397
9398     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9399     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9400
9401     doctype = (void*)0xdeadbeef;
9402     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9403     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9404     ok(doctype == NULL, "got %p\n", doctype);
9405
9406     IXMLDOMDocument_Release(doc);
9407 }
9408
9409 static void test_get_tagName(void)
9410 {
9411     IXMLDOMDocument *doc;
9412     IXMLDOMElement *elem, *elem2;
9413     HRESULT hr;
9414     BSTR str;
9415
9416     doc = create_document(&IID_IXMLDOMDocument);
9417
9418     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9419     ok(hr == S_OK, "got 0x%08x\n", hr);
9420
9421     hr = IXMLDOMElement_get_tagName(elem, NULL);
9422     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9423
9424     str = NULL;
9425     hr = IXMLDOMElement_get_tagName(elem, &str);
9426     ok(hr == S_OK, "got 0x%08x\n", hr);
9427     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9428     SysFreeString(str);
9429
9430     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9431     ok(hr == S_OK, "got 0x%08x\n", hr);
9432
9433     str = NULL;
9434     hr = IXMLDOMElement_get_tagName(elem2, &str);
9435     ok(hr == S_OK, "got 0x%08x\n", hr);
9436     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9437     SysFreeString(str);
9438
9439     IXMLDOMDocument_Release(elem);
9440     IXMLDOMDocument_Release(elem2);
9441     IXMLDOMDocument_Release(doc);
9442     free_bstrs();
9443 }
9444
9445 typedef struct _get_datatype_t {
9446     DOMNodeType type;
9447     const char *name;
9448     VARTYPE vt;
9449     HRESULT hr;
9450 } get_datatype_t;
9451
9452 static const get_datatype_t get_datatype[] = {
9453     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9454     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9455     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9456     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9457     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9458     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9459     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9460     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9461     { 0 }
9462 };
9463
9464 static void test_get_dataType(void)
9465 {
9466     IXMLDOMDocument *doc;
9467     const get_datatype_t *entry = get_datatype;
9468
9469     doc = create_document(&IID_IXMLDOMDocument);
9470
9471     while (entry->type)
9472     {
9473         IXMLDOMNode *node = NULL;
9474         VARIANT var, type;
9475         HRESULT hr;
9476
9477         V_VT(&var) = VT_I4;
9478         V_I4(&var) = entry->type;
9479         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9480         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9481
9482         hr = IXMLDOMNode_get_dataType(node, NULL);
9483         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9484
9485         VariantInit(&type);
9486         hr = IXMLDOMNode_get_dataType(node, &type);
9487         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9488             hr, entry->hr, entry->type);
9489         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9490             V_VT(&type), entry->vt, entry->type);
9491         VariantClear(&type);
9492
9493         IXMLDOMNode_Release(node);
9494
9495         entry++;
9496     }
9497
9498     IXMLDOMDocument_Release(doc);
9499     free_bstrs();
9500 }
9501
9502 typedef struct _get_node_typestring_t {
9503     DOMNodeType type;
9504     const char *string;
9505 } get_node_typestring_t;
9506
9507 static const get_node_typestring_t get_node_typestring[] = {
9508     { NODE_ELEMENT,                "element"               },
9509     { NODE_ATTRIBUTE,              "attribute"             },
9510     { NODE_TEXT,                   "text"                  },
9511     { NODE_CDATA_SECTION ,         "cdatasection"          },
9512     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9513     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9514     { NODE_COMMENT,                "comment"               },
9515     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9516     { 0 }
9517 };
9518
9519 static void test_get_nodeTypeString(void)
9520 {
9521     const get_node_typestring_t *entry = get_node_typestring;
9522     IXMLDOMDocument *doc;
9523     HRESULT hr;
9524     BSTR str;
9525
9526     doc = create_document(&IID_IXMLDOMDocument);
9527
9528     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9529     ok(hr == S_OK, "got 0x%08x\n", hr);
9530     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9531     SysFreeString(str);
9532
9533     while (entry->type)
9534     {
9535         IXMLDOMNode *node = NULL;
9536         VARIANT var;
9537
9538         V_VT(&var) = VT_I4;
9539         V_I4(&var) = entry->type;
9540         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9541         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9542
9543         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9544         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9545
9546         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9547         ok(hr == S_OK, "got 0x%08x\n", hr);
9548         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9549             wine_dbgstr_w(str), entry->string, entry->type);
9550         SysFreeString(str);
9551         IXMLDOMNode_Release(node);
9552
9553         entry++;
9554     }
9555
9556     IXMLDOMDocument_Release(doc);
9557     free_bstrs();
9558 }
9559
9560 typedef struct _get_attributes_t {
9561     DOMNodeType type;
9562     HRESULT hr;
9563 } get_attributes_t;
9564
9565 static const get_attributes_t get_attributes[] = {
9566     { NODE_ATTRIBUTE,              S_FALSE },
9567     { NODE_TEXT,                   S_FALSE },
9568     { NODE_CDATA_SECTION ,         S_FALSE },
9569     { NODE_ENTITY_REFERENCE,       S_FALSE },
9570     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9571     { NODE_COMMENT,                S_FALSE },
9572     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9573     { 0 }
9574 };
9575
9576 static void test_get_attributes(void)
9577 {
9578     const get_attributes_t *entry = get_attributes;
9579     IXMLDOMNamedNodeMap *map;
9580     IXMLDOMDocument *doc;
9581     IXMLDOMNode *node, *node2;
9582     VARIANT_BOOL b;
9583     HRESULT hr;
9584     BSTR str;
9585     LONG length;
9586
9587     doc = create_document(&IID_IXMLDOMDocument);
9588
9589     str = SysAllocString( szComplete4 );
9590     hr = IXMLDOMDocument_loadXML(doc, str, &b);
9591     ok(hr == S_OK, "got %08x\n", hr);
9592     SysFreeString(str);
9593
9594     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9595     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9596
9597     map = (void*)0xdeadbeef;
9598     hr = IXMLDOMDocument_get_attributes(doc, &map);
9599     ok(hr == S_FALSE, "got %08x\n", hr);
9600     ok(map == NULL, "got %p\n", map);
9601
9602     /* first child is <?xml ?> */
9603     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9604     ok(hr == S_OK, "got %08x\n", hr);
9605
9606     hr = IXMLDOMNode_get_attributes(node, &map);
9607     ok(hr == S_OK, "got %08x\n", hr);
9608
9609     length = -1;
9610     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9611     EXPECT_HR(hr, S_OK);
9612     todo_wine ok(length == 1, "got %d\n", length);
9613
9614     if (hr == S_OK && length == 1)
9615     {
9616         IXMLDOMAttribute *attr;
9617         DOMNodeType type;
9618         VARIANT v;
9619
9620         node2 = NULL;
9621         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9622         EXPECT_HR(hr, S_OK);
9623         ok(node != NULL, "got %p\n", node2);
9624
9625         hr = IXMLDOMNode_get_nodeName(node2, &str);
9626         EXPECT_HR(hr, S_OK);
9627         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9628         SysFreeString(str);
9629
9630         length = -1;
9631         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9632         EXPECT_HR(hr, S_OK);
9633         ok(length == 1, "got %d\n", length);
9634
9635         type = -1;
9636         hr = IXMLDOMNode_get_nodeType(node2, &type);
9637         EXPECT_HR(hr, S_OK);
9638         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9639
9640         hr = IXMLDOMNode_get_xml(node, &str);
9641         EXPECT_HR(hr, S_OK);
9642         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9643         SysFreeString(str);
9644
9645         hr = IXMLDOMNode_get_text(node, &str);
9646         EXPECT_HR(hr, S_OK);
9647         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9648         SysFreeString(str);
9649
9650         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9651         EXPECT_HR(hr, S_OK);
9652
9653         length = -1;
9654         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9655         EXPECT_HR(hr, S_OK);
9656         ok(length == 0, "got %d\n", length);
9657
9658         hr = IXMLDOMNode_get_xml(node, &str);
9659         EXPECT_HR(hr, S_OK);
9660         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9661         SysFreeString(str);
9662
9663         hr = IXMLDOMNode_get_text(node, &str);
9664         EXPECT_HR(hr, S_OK);
9665         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9666         SysFreeString(str);
9667
9668         IXMLDOMNamedNodeMap_Release(map);
9669
9670         hr = IXMLDOMNode_get_attributes(node, &map);
9671         ok(hr == S_OK, "got %08x\n", hr);
9672
9673         length = -1;
9674         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9675         EXPECT_HR(hr, S_OK);
9676         ok(length == 0, "got %d\n", length);
9677
9678         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9679         EXPECT_HR(hr, S_OK);
9680
9681         V_VT(&v) = VT_BSTR;
9682         V_BSTR(&v) = _bstr_("UTF-8");
9683         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9684         EXPECT_HR(hr, S_OK);
9685
9686         EXPECT_REF(attr, 2);
9687         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9688         EXPECT_HR(hr, S_OK);
9689         EXPECT_REF(attr, 2);
9690
9691         hr = IXMLDOMNode_get_attributes(node, &map);
9692         ok(hr == S_OK, "got %08x\n", hr);
9693
9694         length = -1;
9695         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9696         EXPECT_HR(hr, S_OK);
9697         ok(length == 1, "got %d\n", length);
9698
9699         hr = IXMLDOMNode_get_xml(node, &str);
9700         EXPECT_HR(hr, S_OK);
9701         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9702         SysFreeString(str);
9703
9704         hr = IXMLDOMNode_get_text(node, &str);
9705         EXPECT_HR(hr, S_OK);
9706         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9707         SysFreeString(str);
9708
9709         IXMLDOMNamedNodeMap_Release(map);
9710         IXMLDOMNode_Release(node2);
9711     }
9712
9713     IXMLDOMNode_Release(node);
9714
9715     /* last child is element */
9716     EXPECT_REF(doc, 1);
9717     hr = IXMLDOMDocument_get_lastChild(doc, &node);
9718     ok(hr == S_OK, "got %08x\n", hr);
9719     EXPECT_REF(doc, 1);
9720
9721     EXPECT_REF(node, 1);
9722     hr = IXMLDOMNode_get_attributes(node, &map);
9723     ok(hr == S_OK, "got %08x\n", hr);
9724     EXPECT_REF(node, 1);
9725     EXPECT_REF(doc, 1);
9726
9727     EXPECT_REF(map, 1);
9728     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9729     ok(hr == S_OK, "got %08x\n", hr);
9730     EXPECT_REF(node, 1);
9731     EXPECT_REF(node2, 1);
9732     EXPECT_REF(map, 1);
9733     EXPECT_REF(doc, 1);
9734     IXMLDOMNode_Release(node2);
9735
9736     /* release node before map release, map still works */
9737     IXMLDOMNode_Release(node);
9738
9739     length = 0;
9740     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9741     ok(hr == S_OK, "got %08x\n", hr);
9742     ok(length == 1, "got %d\n", length);
9743
9744     node2 = NULL;
9745     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9746     ok(hr == S_OK, "got %08x\n", hr);
9747     EXPECT_REF(node2, 1);
9748     IXMLDOMNode_Release(node2);
9749
9750     IXMLDOMNamedNodeMap_Release(map);
9751
9752     while (entry->type)
9753     {
9754         VARIANT var;
9755
9756         node = NULL;
9757
9758         V_VT(&var) = VT_I4;
9759         V_I4(&var) = entry->type;
9760         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9761         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9762
9763         hr = IXMLDOMNode_get_attributes(node, NULL);
9764         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9765
9766         map = (void*)0xdeadbeef;
9767         hr = IXMLDOMNode_get_attributes(node, &map);
9768         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9769             hr, entry->hr, entry->type);
9770         ok(map == NULL, "got %p\n", map);
9771
9772         IXMLDOMNode_Release(node);
9773
9774         entry++;
9775     }
9776
9777     IXMLDOMDocument_Release(doc);
9778     free_bstrs();
9779 }
9780
9781 static void test_selection(void)
9782 {
9783     IXMLDOMSelection *selection, *selection2;
9784     IEnumVARIANT *enum1, *enum2, *enum3;
9785     IXMLDOMNodeList *list;
9786     IXMLDOMDocument *doc;
9787     IDispatchEx *dispex;
9788     IXMLDOMNode *node;
9789     IDispatch *disp;
9790     VARIANT_BOOL b;
9791     HRESULT hr;
9792     DISPID did;
9793     VARIANT v;
9794     BSTR name;
9795     ULONG ret;
9796     LONG len;
9797
9798     doc = create_document(&IID_IXMLDOMDocument);
9799
9800     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
9801     EXPECT_HR(hr, S_OK);
9802
9803     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
9804     EXPECT_HR(hr, S_OK);
9805
9806     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9807     EXPECT_HR(hr, S_OK);
9808     IXMLDOMSelection_Release(selection);
9809
9810     /* collection disp id */
9811     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
9812     EXPECT_HR(hr, S_OK);
9813     did = 0;
9814     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
9815     EXPECT_HR(hr, S_OK);
9816     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
9817     len = 0;
9818     hr = IXMLDOMSelection_get_length(selection, &len);
9819     EXPECT_HR(hr, S_OK);
9820     ok(len == 1, "got %d\n", len);
9821     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
9822     EXPECT_HR(hr, S_OK);
9823     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
9824     IDispatchEx_Release(dispex);
9825
9826     /* IEnumVARIANT tests */
9827     enum1 = NULL;
9828     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
9829     EXPECT_HR(hr, S_OK);
9830     ok(enum1 != NULL, "got %p\n", enum1);
9831     EXPECT_REF(enum1, 2);
9832
9833     enum3 = NULL;
9834     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
9835     EXPECT_HR(hr, S_OK);
9836     ok(enum3 != NULL, "got %p\n", enum3);
9837     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
9838     EXPECT_REF(enum1, 3);
9839     IEnumVARIANT_Release(enum3);
9840
9841     EXPECT_REF(selection, 1);
9842     EXPECT_REF(enum1, 2);
9843
9844     enum2 = NULL;
9845     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9846     EXPECT_HR(hr, S_OK);
9847     ok(enum2 != NULL, "got %p\n", enum2);
9848
9849     EXPECT_REF(selection, 2);
9850     EXPECT_REF(enum1, 2);
9851     EXPECT_REF(enum2, 1);
9852
9853     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
9854
9855     selection2 = NULL;
9856     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
9857     EXPECT_HR(hr, S_OK);
9858     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
9859     EXPECT_REF(selection, 3);
9860     EXPECT_REF(enum1, 2);
9861
9862     IXMLDOMSelection_Release(selection2);
9863
9864     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
9865     EXPECT_HR(hr, S_OK);
9866     EXPECT_REF(selection, 3);
9867     IDispatch_Release(disp);
9868
9869     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
9870     EXPECT_HR(hr, S_OK);
9871     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
9872     EXPECT_REF(selection, 2);
9873     EXPECT_REF(enum1, 3);
9874
9875     IEnumVARIANT_Release(enum1);
9876     IEnumVARIANT_Release(enum2);
9877
9878     enum1 = NULL;
9879     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
9880     EXPECT_HR(hr, S_OK);
9881     ok(enum1 != NULL, "got %p\n", enum1);
9882     EXPECT_REF(enum1, 1);
9883     EXPECT_REF(selection, 2);
9884
9885     enum2 = NULL;
9886     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9887     EXPECT_HR(hr, S_OK);
9888     ok(enum2 != NULL, "got %p\n", enum2);
9889     EXPECT_REF(enum2, 1);
9890     EXPECT_REF(selection, 3);
9891
9892     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
9893
9894     IEnumVARIANT_AddRef(enum1);
9895     EXPECT_REF(selection, 3);
9896     EXPECT_REF(enum1, 2);
9897     EXPECT_REF(enum2, 1);
9898     IEnumVARIANT_Release(enum1);
9899
9900     IEnumVARIANT_Release(enum1);
9901     IEnumVARIANT_Release(enum2);
9902
9903     EXPECT_REF(selection, 1);
9904
9905     IXMLDOMNodeList_Release(list);
9906
9907     hr = IXMLDOMDocument_get_childNodes(doc, &list);
9908     EXPECT_HR(hr, S_OK);
9909
9910     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9911     EXPECT_HR(hr, E_NOINTERFACE);
9912
9913     IXMLDOMNodeList_Release(list);
9914
9915     /* test if IEnumVARIANT touches selection context */
9916     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
9917     EXPECT_HR(hr, S_OK);
9918
9919     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
9920     EXPECT_HR(hr, S_OK);
9921
9922     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9923     EXPECT_HR(hr, S_OK);
9924
9925     len = 0;
9926     hr = IXMLDOMSelection_get_length(selection, &len);
9927     EXPECT_HR(hr, S_OK);
9928     ok(len == 4, "got %d\n", len);
9929
9930     enum1 = NULL;
9931     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
9932     EXPECT_HR(hr, S_OK);
9933
9934     /* no-op if zero count */
9935     V_VT(&v) = VT_I2;
9936     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
9937     EXPECT_HR(hr, S_OK);
9938     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
9939
9940     /* positive count, null array pointer */
9941     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
9942     EXPECT_HR(hr, E_INVALIDARG);
9943
9944     ret = 1;
9945     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
9946     EXPECT_HR(hr, E_INVALIDARG);
9947     ok(ret == 0, "got %d\n", ret);
9948
9949     V_VT(&v) = VT_I2;
9950     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
9951     EXPECT_HR(hr, S_OK);
9952     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
9953
9954     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
9955     EXPECT_HR(hr, S_OK);
9956     hr = IXMLDOMNode_get_nodeName(node, &name);
9957     EXPECT_HR(hr, S_OK);
9958     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
9959     SysFreeString(name);
9960     IXMLDOMNode_Release(node);
9961     VariantClear(&v);
9962
9963     /* list cursor is updated */
9964     hr = IXMLDOMSelection_nextNode(selection, &node);
9965     EXPECT_HR(hr, S_OK);
9966     hr = IXMLDOMNode_get_nodeName(node, &name);
9967     EXPECT_HR(hr, S_OK);
9968     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
9969     IXMLDOMNode_Release(node);
9970
9971     V_VT(&v) = VT_I2;
9972     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
9973     EXPECT_HR(hr, S_OK);
9974     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
9975     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
9976     EXPECT_HR(hr, S_OK);
9977     hr = IXMLDOMNode_get_nodeName(node, &name);
9978     EXPECT_HR(hr, S_OK);
9979     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
9980     SysFreeString(name);
9981     IXMLDOMNode_Release(node);
9982     VariantClear(&v);
9983
9984     hr = IXMLDOMSelection_nextNode(selection, &node);
9985     EXPECT_HR(hr, S_OK);
9986     hr = IXMLDOMNode_get_nodeName(node, &name);
9987     EXPECT_HR(hr, S_OK);
9988     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
9989     IXMLDOMNode_Release(node);
9990
9991     IXMLDOMSelection_Release(selection);
9992     IXMLDOMNodeList_Release(list);
9993     IXMLDOMDocument_Release(doc);
9994
9995     free_bstrs();
9996 }
9997
9998 static void test_load(void)
9999 {
10000     IXMLDOMDocument *doc;
10001     IXMLDOMNodeList *list;
10002     VARIANT_BOOL b;
10003     HANDLE hfile;
10004     VARIANT src;
10005     HRESULT hr;
10006     BOOL ret;
10007     BSTR path, bstr1, bstr2;
10008     DWORD written;
10009     void* ptr;
10010
10011     /* prepare a file */
10012     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10013     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10014     if(hfile == INVALID_HANDLE_VALUE) return;
10015
10016     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10017     ok(ret, "WriteFile failed\n");
10018
10019     CloseHandle(hfile);
10020
10021     doc = create_document(&IID_IXMLDOMDocument);
10022
10023     path = _bstr_("test.xml");
10024
10025     /* load from path: VT_BSTR */
10026     V_VT(&src) = VT_BSTR;
10027     V_BSTR(&src) = path;
10028     hr = IXMLDOMDocument_load(doc, src, &b);
10029     EXPECT_HR(hr, S_OK);
10030     ok(b == VARIANT_TRUE, "got %d\n", b);
10031
10032     /* load from a path: VT_BSTR|VT_BYREF */
10033     V_VT(&src) = VT_BSTR | VT_BYREF;
10034     V_BSTRREF(&src) = &path;
10035     hr = IXMLDOMDocument_load(doc, src, &b);
10036     EXPECT_HR(hr, S_OK);
10037     ok(b == VARIANT_TRUE, "got %d\n", b);
10038
10039     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10040     V_VT(&src) = VT_BSTR | VT_BYREF;
10041     V_BSTRREF(&src) = NULL;
10042     hr = IXMLDOMDocument_load(doc, src, &b);
10043     EXPECT_HR(hr, E_INVALIDARG);
10044     ok(b == VARIANT_FALSE, "got %d\n", b);
10045
10046     IXMLDOMDocument_Release(doc);
10047
10048     DeleteFileA("test.xml");
10049
10050     doc = create_document(&IID_IXMLDOMDocument);
10051
10052     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10053     EXPECT_HR(hr, S_OK);
10054     ok(b == VARIANT_TRUE, "got %d\n", b);
10055
10056     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10057     EXPECT_HR(hr, S_OK);
10058     bstr1 = _bstr_(list_to_string(list));
10059
10060     hr = IXMLDOMNodeList_reset(list);
10061     EXPECT_HR(hr, S_OK);
10062
10063     IXMLDOMDocument_Release(doc);
10064
10065     doc = create_document(&IID_IXMLDOMDocument);
10066
10067     VariantInit(&src);
10068     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10069     V_VT(&src) = VT_ARRAY|VT_UI1;
10070     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10071     ptr = NULL;
10072     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10073     EXPECT_HR(hr, S_OK);
10074     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10075
10076     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10077     hr = SafeArrayUnlock(V_ARRAY(&src));
10078     EXPECT_HR(hr, S_OK);
10079
10080     hr = IXMLDOMDocument_load(doc, src, &b);
10081     EXPECT_HR(hr, S_OK);
10082     ok(b == VARIANT_TRUE, "got %d\n", b);
10083
10084     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10085     EXPECT_HR(hr, S_OK);
10086     bstr2 = _bstr_(list_to_string(list));
10087
10088     hr = IXMLDOMNodeList_reset(list);
10089     EXPECT_HR(hr, S_OK);
10090
10091     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10092        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10093
10094     IXMLDOMDocument_Release(doc);
10095     IXMLDOMNodeList_Release(list);
10096     VariantClear(&src);
10097
10098     /* UTF-16 isn't accepted */
10099     doc = create_document(&IID_IXMLDOMDocument);
10100
10101     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10102     V_VT(&src) = VT_ARRAY|VT_UI1;
10103     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10104     ptr = NULL;
10105     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10106     EXPECT_HR(hr, S_OK);
10107     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10108
10109     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10110     hr = SafeArrayUnlock(V_ARRAY(&src));
10111     EXPECT_HR(hr, S_OK);
10112
10113     hr = IXMLDOMDocument_load(doc, src, &b);
10114     todo_wine EXPECT_HR(hr, S_FALSE);
10115     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10116
10117     VariantClear(&src);
10118
10119     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10120     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10121     V_VT(&src) = VT_ARRAY|VT_UI2;
10122     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10123     ptr = NULL;
10124     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10125     EXPECT_HR(hr, S_OK);
10126     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10127
10128     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10129     hr = SafeArrayUnlock(V_ARRAY(&src));
10130     EXPECT_HR(hr, S_OK);
10131
10132     hr = IXMLDOMDocument_load(doc, src, &b);
10133     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10134     ok(b == VARIANT_FALSE, "got %d\n", b);
10135
10136     VariantClear(&src);
10137     IXMLDOMDocument_Release(doc);
10138
10139     free_bstrs();
10140 }
10141
10142 static void test_nsnamespacemanager(void)
10143 {
10144     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10145     IMXNamespaceManager *nsmgr;
10146     IVBMXNamespaceManager *mgr2;
10147     IDispatch *disp;
10148     HRESULT hr;
10149     WCHAR buffW[250];
10150     INT len;
10151
10152     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10153         &IID_IMXNamespaceManager, (void**)&nsmgr);
10154     if (hr != S_OK)
10155     {
10156         win_skip("MXNamespaceManager is not available\n");
10157         return;
10158     }
10159
10160     /* IMXNamespaceManager inherits from IUnknown */
10161     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10162     EXPECT_HR(hr, S_OK);
10163     IDispatch_Release(disp);
10164
10165     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10166     EXPECT_HR(hr, S_OK);
10167     IVBMXNamespaceManager_Release(mgr2);
10168
10169     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10170     EXPECT_HR(hr, S_OK);
10171
10172     /* prefix already added */
10173     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10174     EXPECT_HR(hr, S_FALSE);
10175
10176     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10177     EXPECT_HR(hr, E_INVALIDARG);
10178
10179     /* "xml" and "xmlns" are not allowed here */
10180     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10181     EXPECT_HR(hr, E_INVALIDARG);
10182
10183     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10184     EXPECT_HR(hr, E_INVALIDARG);
10185 todo_wine {
10186     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10187     EXPECT_HR(hr, E_FAIL);
10188 }
10189     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10190     EXPECT_HR(hr, E_POINTER);
10191
10192     len = -1;
10193     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10194     EXPECT_HR(hr, S_OK);
10195     ok(len == 3, "got %d\n", len);
10196
10197     len = -1;
10198     buffW[0] = 0x1;
10199     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10200     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10201     ok(len == -1, "got %d\n", len);
10202     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10203
10204     len = 10;
10205     buffW[0] = 0x1;
10206     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10207     EXPECT_HR(hr, S_OK);
10208     ok(len == 3, "got %d\n", len);
10209     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10210
10211     /* getURI */
10212     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10213     EXPECT_HR(hr, E_INVALIDARG);
10214
10215     len = -1;
10216     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10217     EXPECT_HR(hr, E_INVALIDARG);
10218     ok(len == -1, "got %d\n", len);
10219
10220     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10221     EXPECT_HR(hr, E_POINTER);
10222
10223     len = -1;
10224     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10225     EXPECT_HR(hr, S_OK);
10226     /* length of "xml" uri is constant */
10227     ok(len == strlen(xmluriA), "got %d\n", len);
10228
10229     len = 100;
10230     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10231     EXPECT_HR(hr, S_OK);
10232     ok(len == strlen(xmluriA), "got %d\n", len);
10233     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10234
10235     len = strlen(xmluriA)-1;
10236     buffW[0] = 0x1;
10237     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10238     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10239     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10240     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10241
10242     /* prefix xml1 not defined */
10243     len = -1;
10244     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10245     EXPECT_HR(hr, S_FALSE);
10246     ok(len == 0, "got %d\n", len);
10247
10248     len = 100;
10249     buffW[0] = 0x1;
10250     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10251     EXPECT_HR(hr, S_FALSE);
10252     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10253     ok(len == 0, "got %d\n", len);
10254
10255     IMXNamespaceManager_Release(nsmgr);
10256
10257     free_bstrs();
10258 }
10259
10260 static void test_nsnamespacemanager_override(void)
10261 {
10262     IMXNamespaceManager *nsmgr;
10263     WCHAR buffW[250];
10264     VARIANT_BOOL b;
10265     HRESULT hr;
10266     INT len;
10267
10268     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10269         &IID_IMXNamespaceManager, (void**)&nsmgr);
10270     if (hr != S_OK)
10271     {
10272         win_skip("MXNamespaceManager is not available\n");
10273         return;
10274     }
10275
10276     len = sizeof(buffW)/sizeof(WCHAR);
10277     buffW[0] = 0;
10278     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10279     EXPECT_HR(hr, S_OK);
10280     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10281
10282     len = sizeof(buffW)/sizeof(WCHAR);
10283     buffW[0] = 0;
10284     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10285     EXPECT_HR(hr, E_FAIL);
10286
10287     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10288     EXPECT_HR(hr, E_POINTER);
10289
10290     b = VARIANT_FALSE;
10291     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10292     EXPECT_HR(hr, S_OK);
10293     ok(b == VARIANT_TRUE, "got %d\n", b);
10294
10295     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10296     EXPECT_HR(hr, S_OK);
10297
10298     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10299     EXPECT_HR(hr, S_OK);
10300
10301     len = sizeof(buffW)/sizeof(WCHAR);
10302     buffW[0] = 0;
10303     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10304     EXPECT_HR(hr, S_OK);
10305     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10306
10307     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10308     EXPECT_HR(hr, S_OK);
10309
10310     len = sizeof(buffW)/sizeof(WCHAR);
10311     buffW[0] = 0;
10312     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10313     EXPECT_HR(hr, S_OK);
10314     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10315
10316     len = sizeof(buffW)/sizeof(WCHAR);
10317     buffW[0] = 0;
10318     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10319     EXPECT_HR(hr, S_OK);
10320     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10321
10322     len = sizeof(buffW)/sizeof(WCHAR);
10323     buffW[0] = 0;
10324     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10325     EXPECT_HR(hr, S_OK);
10326     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10327
10328     /* new prefix placed at index 1 always */
10329     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10330     EXPECT_HR(hr, S_OK);
10331
10332     len = sizeof(buffW)/sizeof(WCHAR);
10333     buffW[0] = 0;
10334     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10335     EXPECT_HR(hr, S_OK);
10336     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10337
10338     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10339     todo_wine EXPECT_HR(hr, E_FAIL);
10340
10341     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10342     EXPECT_HR(hr, E_FAIL);
10343
10344     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10345     EXPECT_HR(hr, E_FAIL);
10346
10347     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10348     EXPECT_HR(hr, S_OK);
10349
10350     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10351     EXPECT_HR(hr, S_FALSE);
10352
10353     len = sizeof(buffW)/sizeof(WCHAR);
10354     buffW[0] = 0;
10355     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10356     EXPECT_HR(hr, S_OK);
10357     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10358
10359     len = sizeof(buffW)/sizeof(WCHAR);
10360     buffW[0] = 0;
10361     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10362     EXPECT_HR(hr, S_OK);
10363     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10364
10365     IMXNamespaceManager_Release(nsmgr);
10366
10367     free_bstrs();
10368 }
10369
10370 static void test_domobj_dispex(IUnknown *obj)
10371 {
10372     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10373     IDispatchEx *dispex;
10374     IUnknown *unk;
10375     DWORD props;
10376     UINT ticnt;
10377     HRESULT hr;
10378     BSTR name;
10379
10380     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10381     EXPECT_HR(hr, S_OK);
10382     if (FAILED(hr)) return;
10383
10384     ticnt = 0;
10385     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10386     EXPECT_HR(hr, S_OK);
10387     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10388
10389     name = SysAllocString(szstar);
10390     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10391     EXPECT_HR(hr, E_NOTIMPL);
10392     SysFreeString(name);
10393
10394     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10395     EXPECT_HR(hr, E_NOTIMPL);
10396
10397     props = 0;
10398     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10399     EXPECT_HR(hr, E_NOTIMPL);
10400     ok(props == 0, "expected 0 got %d\n", props);
10401
10402     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10403     EXPECT_HR(hr, E_NOTIMPL);
10404     if (SUCCEEDED(hr)) SysFreeString(name);
10405
10406     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10407     EXPECT_HR(hr, E_NOTIMPL);
10408
10409     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10410     EXPECT_HR(hr, E_NOTIMPL);
10411     if (hr == S_OK && unk) IUnknown_Release(unk);
10412
10413     IDispatchEx_Release(dispex);
10414 }
10415
10416 static const DOMNodeType dispex_types_test[] =
10417 {
10418     NODE_ELEMENT,
10419     NODE_ATTRIBUTE,
10420     NODE_TEXT,
10421     NODE_CDATA_SECTION,
10422     NODE_ENTITY_REFERENCE,
10423     NODE_PROCESSING_INSTRUCTION,
10424     NODE_COMMENT,
10425     NODE_DOCUMENT_FRAGMENT,
10426     NODE_INVALID
10427 };
10428
10429 static void test_dispex(void)
10430 {
10431     const DOMNodeType *type = dispex_types_test;
10432     IXMLDOMNodeList *node_list;
10433     IXMLDOMParseError *error;
10434     IXMLDOMNamedNodeMap *map;
10435     IXMLDOMDocument *doc;
10436     IXMLHTTPRequest *req;
10437     IXMLDOMElement *elem;
10438     IDispatchEx *dispex;
10439     IXMLDOMNode *node;
10440     VARIANT_BOOL b;
10441     IUnknown *unk;
10442     HRESULT hr;
10443     DISPID did;
10444
10445     doc = create_document(&IID_IXMLDOMDocument);
10446
10447     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10448     test_domobj_dispex(unk);
10449     IUnknown_Release(unk);
10450
10451     for(; *type != NODE_INVALID; type++)
10452     {
10453         IXMLDOMNode *node;
10454         VARIANT v;
10455
10456         V_VT(&v) = VT_I2;
10457         V_I2(&v) = *type;
10458
10459         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10460         ok(hr == S_OK, "failed to create node type %d\n", *type);
10461
10462         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10463
10464         test_domobj_dispex(unk);
10465         IUnknown_Release(unk);
10466         IXMLDOMNode_Release(node);
10467     }
10468
10469     /* IXMLDOMNodeList */
10470     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10471     EXPECT_HR(hr, S_OK);
10472     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10473     test_domobj_dispex(unk);
10474     IUnknown_Release(unk);
10475     IXMLDOMNodeList_Release(node_list);
10476
10477     /* IXMLDOMParseError */
10478     hr = IXMLDOMDocument_get_parseError(doc, &error);
10479     EXPECT_HR(hr, S_OK);
10480     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
10481     test_domobj_dispex(unk);
10482     IUnknown_Release(unk);
10483     IXMLDOMParseError_Release(error);
10484
10485     /* IXMLDOMNamedNodeMap */
10486     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10487     EXPECT_HR(hr, S_OK);
10488
10489     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
10490     EXPECT_HR(hr, S_OK);
10491     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10492     EXPECT_HR(hr, S_OK);
10493     IXMLDOMNodeList_Release(node_list);
10494
10495     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10496     EXPECT_HR(hr, S_OK);
10497     IXMLDOMNode_Release(node);
10498     hr = IXMLDOMElement_get_attributes(elem, &map);
10499     EXPECT_HR(hr, S_OK);
10500     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
10501     test_domobj_dispex(unk);
10502     IUnknown_Release(unk);
10503     /* collection dispex test */
10504     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10505     EXPECT_HR(hr, S_OK);
10506     did = 0;
10507     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10508     EXPECT_HR(hr, S_OK);
10509     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10510     IDispatchEx_Release(dispex);
10511
10512     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
10513     EXPECT_HR(hr, S_OK);
10514     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10515     EXPECT_HR(hr, S_OK);
10516     IXMLDOMNodeList_Release(node_list);
10517     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10518     EXPECT_HR(hr, S_OK);
10519     IXMLDOMNode_Release(node);
10520     hr = IXMLDOMElement_get_attributes(elem, &map);
10521     EXPECT_HR(hr, S_OK);
10522     /* collection dispex test, empty collection */
10523     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10524     EXPECT_HR(hr, S_OK);
10525     did = 0;
10526     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10527     EXPECT_HR(hr, S_OK);
10528     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10529     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10530     EXPECT_HR(hr, S_OK);
10531     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10532     IDispatchEx_Release(dispex);
10533
10534     IXMLDOMNamedNodeMap_Release(map);
10535     IXMLDOMElement_Release(elem);
10536
10537     IXMLDOMDocument_Release(doc);
10538
10539     /* IXMLHTTPRequest */
10540     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
10541         &IID_IXMLHttpRequest, (void**)&req);
10542     if (hr == S_OK)
10543     {
10544         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
10545         EXPECT_HR(hr, E_NOINTERFACE);
10546         IXMLHTTPRequest_Release(req);
10547     }
10548
10549     free_bstrs();
10550 }
10551
10552 static void test_parseerror(void)
10553 {
10554     IXMLDOMParseError *error;
10555     IXMLDOMDocument *doc;
10556     HRESULT hr;
10557
10558     doc = create_document(&IID_IXMLDOMDocument);
10559
10560     hr = IXMLDOMDocument_get_parseError(doc, &error);
10561     EXPECT_HR(hr, S_OK);
10562
10563     hr = IXMLDOMParseError_get_line(error, NULL);
10564     EXPECT_HR(hr, E_INVALIDARG);
10565
10566     hr = IXMLDOMParseError_get_srcText(error, NULL);
10567     EXPECT_HR(hr, E_INVALIDARG);
10568
10569     hr = IXMLDOMParseError_get_linepos(error, NULL);
10570     EXPECT_HR(hr, E_INVALIDARG);
10571
10572     IXMLDOMParseError_Release(error);
10573
10574     IXMLDOMDocument_Release(doc);
10575 }
10576
10577 START_TEST(domdoc)
10578 {
10579     IXMLDOMDocument *doc;
10580     HRESULT hr;
10581
10582     hr = CoInitialize( NULL );
10583     ok( hr == S_OK, "failed to init com\n");
10584     if (hr != S_OK) return;
10585
10586     test_XMLHTTP();
10587
10588     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
10589     if (hr != S_OK)
10590     {
10591         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
10592         return;
10593     }
10594
10595     IXMLDOMDocument_Release(doc);
10596
10597     test_domdoc();
10598     test_persiststreaminit();
10599     test_domnode();
10600     test_refs();
10601     test_create();
10602     test_getElementsByTagName();
10603     test_get_text();
10604     test_get_childNodes();
10605     test_get_firstChild();
10606     test_get_lastChild();
10607     test_removeChild();
10608     test_replaceChild();
10609     test_removeNamedItem();
10610     test_IXMLDOMDocument2();
10611     test_whitespace();
10612     test_XPath();
10613     test_XSLPattern();
10614     test_cloneNode();
10615     test_xmlTypes();
10616     test_nodeTypeTests();
10617     test_save();
10618     test_testTransforms();
10619     test_Namespaces();
10620     test_FormattingXML();
10621     test_nodeTypedValue();
10622     test_TransformWithLoadingLocalFile();
10623     test_put_nodeValue();
10624     test_document_IObjectSafety();
10625     test_splitText();
10626     test_getQualifiedItem();
10627     test_removeQualifiedItem();
10628     test_get_ownerDocument();
10629     test_setAttributeNode();
10630     test_put_dataType();
10631     test_createNode();
10632     test_get_prefix();
10633     test_default_properties();
10634     test_selectSingleNode();
10635     test_events();
10636     test_createProcessingInstruction();
10637     test_put_nodeTypedValue();
10638     test_get_xml();
10639     test_insertBefore();
10640     test_appendChild();
10641     test_get_doctype();
10642     test_get_tagName();
10643     test_get_dataType();
10644     test_get_nodeTypeString();
10645     test_get_attributes();
10646     test_selection();
10647     test_load();
10648     test_dispex();
10649     test_parseerror();
10650
10651     test_xsltemplate();
10652
10653     test_nsnamespacemanager();
10654     test_nsnamespacemanager_override();
10655
10656     CoUninitialize();
10657 }