msxml3: Fix support for IXMLDOMDocument3.
[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 char complete4A[] =
1355     "<?xml version=\'1.0\'?>\n"
1356     "<lc dl=\'str1\'>\n"
1357         "<bs vr=\'str2\' sz=\'1234\'>"
1358             "fn1.txt\n"
1359         "</bs>\n"
1360         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1361             "fn2.txt\n"
1362         "</pr>\n"
1363         "<empty></empty>\n"
1364         "<fo>\n"
1365             "<ba>\n"
1366                 "f1\n"
1367             "</ba>\n"
1368         "</fo>\n"
1369     "</lc>\n";
1370
1371 static const WCHAR szComplete5[] = {
1372     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1373     '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','"',
1374     ' ','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','"','>',
1375         '<','S',':','s','c','o','p','e','>',
1376             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1377         '<','/','S',':','s','c','o','p','e','>',
1378         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1379             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1380             'c','o','m','p','u','t','e','r',
1381         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1382     '<','/','S',':','s','e','a','r','c','h','>',0
1383 };
1384
1385 static const WCHAR szComplete6[] = {
1386     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1387     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1388     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1389 };
1390
1391 static const CHAR szNonUnicodeXML[] =
1392 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1393 "<open></open>\n";
1394
1395 static const char szExampleXML[] =
1396 "<?xml version='1.0' encoding='utf-8'?>\n"
1397 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1398 "    <elem>\n"
1399 "        <a>A1 field</a>\n"
1400 "        <b>B1 field</b>\n"
1401 "        <c>C1 field</c>\n"
1402 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1403 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1404 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1405 "            </html>\n"
1406 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1407 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1408 "            </html>\n"
1409 "        </description>\n"
1410 "    </elem>\n"
1411 "\n"
1412 "    <elem>\n"
1413 "        <a>A2 field</a>\n"
1414 "        <b>B2 field</b>\n"
1415 "        <c type=\"old\">C2 field</c>\n"
1416 "    </elem>\n"
1417 "\n"
1418 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1419 "        <a>A3 field</a>\n"
1420 "        <b>B3 field</b>\n"
1421 "        <c>C3 field</c>\n"
1422 "    </elem>\n"
1423 "\n"
1424 "    <elem>\n"
1425 "        <a>A4 field</a>\n"
1426 "        <b>B4 field</b>\n"
1427 "        <foo:c>C4 field</foo:c>\n"
1428 "    </elem>\n"
1429 "</root>\n";
1430
1431 static const CHAR szNodeTypesXML[] =
1432 "<?xml version='1.0'?>"
1433 "<!-- comment node 0 -->"
1434 "<root id='0' depth='0'>"
1435 "   <!-- comment node 1 -->"
1436 "   text node 0"
1437 "   <x id='1' depth='1'>"
1438 "       <?foo value='PI for x'?>"
1439 "       <!-- comment node 2 -->"
1440 "       text node 1"
1441 "       <a id='3' depth='2'/>"
1442 "       <b id='4' depth='2'/>"
1443 "       <c id='5' depth='2'/>"
1444 "   </x>"
1445 "   <y id='2' depth='1'>"
1446 "       <?bar value='PI for y'?>"
1447 "       <!-- comment node 3 -->"
1448 "       text node 2"
1449 "       <a id='6' depth='2'/>"
1450 "       <b id='7' depth='2'/>"
1451 "       <c id='8' depth='2'/>"
1452 "   </y>"
1453 "</root>";
1454
1455 static const CHAR szTransformXML[] =
1456 "<?xml version=\"1.0\"?>\n"
1457 "<greeting>\n"
1458 "Hello World\n"
1459 "</greeting>";
1460
1461 static  const CHAR szTransformSSXML[] =
1462 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1463 "   <xsl:output method=\"html\"/>\n"
1464 "   <xsl:template match=\"/\">\n"
1465 "       <xsl:apply-templates select=\"greeting\"/>\n"
1466 "   </xsl:template>\n"
1467 "   <xsl:template match=\"greeting\">\n"
1468 "       <html>\n"
1469 "           <body>\n"
1470 "               <h1>\n"
1471 "                   <xsl:value-of select=\".\"/>\n"
1472 "               </h1>\n"
1473 "           </body>\n"
1474 "       </html>\n"
1475 "   </xsl:template>\n"
1476 "</xsl:stylesheet>";
1477
1478 static  const CHAR szTransformOutput[] =
1479 "<html><body><h1>"
1480 "Hello World"
1481 "</h1></body></html>";
1482
1483 static const CHAR szTypeValueXML[] =
1484 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1485 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1486 "   <string>Wine</string>\n"
1487 "   <string2 dt:dt=\"string\">String</string2>\n"
1488 "   <number dt:dt=\"number\">12.44</number>\n"
1489 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1490 "   <int dt:dt=\"int\">-13</int>\n"
1491 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1492 "   <bool dt:dt=\"boolean\">1</bool>\n"
1493 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1494 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1495 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1496 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1497 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1498 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1499 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1500 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1501 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1502 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1503 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1504 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1505 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1506 "   <float dt:dt=\"float\">41221.421</float>\n"
1507 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1508 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1509 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1510 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1511 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1512 "</root>";
1513
1514 static const CHAR szBasicTransformSSXMLPart1[] =
1515 "<?xml version=\"1.0\"?>"
1516 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1517 "<xsl:output method=\"html\"/>\n"
1518 "<xsl:template match=\"/\">"
1519 "<HTML><BODY><TABLE>"
1520 "        <xsl:apply-templates select='document(\"";
1521
1522 static const CHAR szBasicTransformSSXMLPart2[] =
1523 "\")/bottle/wine'>"
1524 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1525 "        </xsl:apply-templates>"
1526 "</TABLE></BODY></HTML>"
1527 "</xsl:template>"
1528 "<xsl:template match=\"bottle\">"
1529 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1530 "</xsl:template>"
1531 "<xsl:template match=\"name\">"
1532 "   <TD><xsl:apply-templates /></TD>"
1533 "</xsl:template>"
1534 "<xsl:template match=\"cost\">"
1535 "   <TD><xsl:apply-templates /></TD>"
1536 "</xsl:template>"
1537 "</xsl:stylesheet>";
1538
1539 static const CHAR szBasicTransformXML[] =
1540 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1541
1542 static const CHAR szBasicTransformOutput[] =
1543 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1544
1545 #define SZ_EMAIL_DTD \
1546 "<!DOCTYPE email ["\
1547 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1548 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1549 "       <!ATTLIST email sent (yes|no) \"no\">"\
1550 "   <!ELEMENT recipients    (to+,cc*)>"\
1551 "   <!ELEMENT to            (#PCDATA)>"\
1552 "       <!ATTLIST to name CDATA #IMPLIED>"\
1553 "   <!ELEMENT cc            (#PCDATA)>"\
1554 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1555 "   <!ELEMENT from          (#PCDATA)>"\
1556 "       <!ATTLIST from name CDATA #IMPLIED>"\
1557 "   <!ELEMENT reply-to      (#PCDATA)>"\
1558 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1559 "   <!ELEMENT subject       ANY>"\
1560 "   <!ELEMENT body          ANY>"\
1561 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1562 "   <!ELEMENT attachment    (#PCDATA)>"\
1563 "       <!ATTLIST attachment id ID #REQUIRED>"\
1564 "]>"
1565
1566 static const CHAR szEmailXML[] =
1567 "<?xml version=\"1.0\"?>"
1568 SZ_EMAIL_DTD
1569 "<email attachments=\"patch1\">"
1570 "   <recipients>"
1571 "       <to>wine-patches@winehq.org</to>"
1572 "   </recipients>"
1573 "   <from name=\"Anonymous\">user@localhost</from>"
1574 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1575 "   <body>"
1576 "       It no longer causes spontaneous combustion..."
1577 "   </body>"
1578 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1579 "</email>";
1580
1581 static const CHAR szEmailXML_0D[] =
1582 "<?xml version=\"1.0\"?>"
1583 SZ_EMAIL_DTD
1584 "<email attachments=\"patch1\">"
1585 "   <recipients>"
1586 "       <to>wine-patches@winehq.org</to>"
1587 "   </recipients>"
1588 "   <from name=\"Anonymous\">user@localhost</from>"
1589 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1590 "   <body>"
1591 "       <undecl />"
1592 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1593 "   </body>"
1594 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1595 "</email>";
1596
1597 static const CHAR szEmailXML_0E[] =
1598 "<?xml version=\"1.0\"?>"
1599 SZ_EMAIL_DTD
1600 "<email attachments=\"patch1\">"
1601 "   <recipients>"
1602 "       <to>wine-patches@winehq.org</to>"
1603 "   </recipients>"
1604 "   <from name=\"Anonymous\">user@localhost</from>"
1605 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1606 "   <body>"
1607 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1608 "   </body>"
1609 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1610 "</email>";
1611
1612 static const CHAR szEmailXML_11[] =
1613 "<?xml version=\"1.0\"?>"
1614 SZ_EMAIL_DTD
1615 "<email attachments=\"patch1\">"
1616 "   <recipients>"
1617 "   </recipients>"
1618 "   <from name=\"Anonymous\">user@localhost</from>"
1619 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1620 "   <body>"
1621 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1622 "   </body>"
1623 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1624 "</email>";
1625
1626 static const CHAR szEmailXML_13[] =
1627 "<?xml version=\"1.0\"?>"
1628 SZ_EMAIL_DTD
1629 "<msg attachments=\"patch1\">"
1630 "   <recipients>"
1631 "       <to>wine-patches@winehq.org</to>"
1632 "   </recipients>"
1633 "   <from name=\"Anonymous\">user@localhost</from>"
1634 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1635 "   <body>"
1636 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1637 "   </body>"
1638 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1639 "</msg>";
1640
1641 static const CHAR szEmailXML_14[] =
1642 "<?xml version=\"1.0\"?>"
1643 SZ_EMAIL_DTD
1644 "<email attachments=\"patch1\">"
1645 "   <to>wine-patches@winehq.org</to>"
1646 "   <from name=\"Anonymous\">user@localhost</from>"
1647 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1648 "   <body>"
1649 "       XML_INVALID_CONTENT 0xC00CE014"
1650 "   </body>"
1651 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1652 "</email>";
1653
1654 static const CHAR szEmailXML_15[] =
1655 "<?xml version=\"1.0\"?>"
1656 SZ_EMAIL_DTD
1657 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1658 "   <recipients>"
1659 "       <to>wine-patches@winehq.org</to>"
1660 "   </recipients>"
1661 "   <from name=\"Anonymous\">user@localhost</from>"
1662 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1663 "   <body>"
1664 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1665 "   </body>"
1666 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1667 "</email>";
1668
1669 static const CHAR szEmailXML_16[] =
1670 "<?xml version=\"1.0\"?>"
1671 SZ_EMAIL_DTD
1672 "<email attachments=\"patch1\">"
1673 "   <recipients>"
1674 "       <to>wine-patches@winehq.org</to>"
1675 "   </recipients>"
1676 "   <from name=\"Anonymous\">user@localhost</from>"
1677 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1678 "   <body enc=\"ASCII\">"
1679 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1680 "   </body>"
1681 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1682 "</email>";
1683
1684 static const CHAR szEmailXML_17[] =
1685 "<?xml version=\"1.0\"?>"
1686 SZ_EMAIL_DTD
1687 "<email attachments=\"patch1\" sent=\"true\">"
1688 "   <recipients>"
1689 "       <to>wine-patches@winehq.org</to>"
1690 "   </recipients>"
1691 "   <from name=\"Anonymous\">user@localhost</from>"
1692 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1693 "   <body>"
1694 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1695 "   </body>"
1696 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1697 "</email>";
1698
1699 static const CHAR szEmailXML_18[] =
1700 "<?xml version=\"1.0\"?>"
1701 SZ_EMAIL_DTD
1702 "<email attachments=\"patch1\">"
1703 "   oops"
1704 "   <recipients>"
1705 "       <to>wine-patches@winehq.org</to>"
1706 "   </recipients>"
1707 "   <from name=\"Anonymous\">user@localhost</from>"
1708 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1709 "   <body>"
1710 "       XML_ILLEGAL_TEXT 0xC00CE018"
1711 "   </body>"
1712 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1713 "</email>";
1714
1715 static const CHAR szEmailXML_20[] =
1716 "<?xml version=\"1.0\"?>"
1717 SZ_EMAIL_DTD
1718 "<email>"
1719 "   <recipients>"
1720 "       <to>wine-patches@winehq.org</to>"
1721 "   </recipients>"
1722 "   <from name=\"Anonymous\">user@localhost</from>"
1723 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1724 "   <body>"
1725 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1726 "   </body>"
1727 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1728 "</email>";
1729
1730 static const char xpath_simple_list[] =
1731 "<?xml version=\"1.0\"?>"
1732 "<root>"
1733 "   <a attr1=\"1\" attr2=\"2\" />"
1734 "   <b/>"
1735 "   <c/>"
1736 "   <d/>"
1737 "</root>";
1738
1739 static const char* leading_spaces[] = {
1740     "\n<?xml version=\"1.0\"?><root/>",
1741     " <?xml version=\"1.0\"?><root/>",
1742     "\t<?xml version=\"1.0\"?><root/>",
1743     "\r\n<?xml version=\"1.0\"?><root/>",
1744     "\r<?xml version=\"1.0\"?><root/>",
1745     0
1746 };
1747
1748 static const char default_ns_doc[] = {
1749     "<?xml version=\"1.0\"?>"
1750     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1751     "    d=\"d attr\" />"
1752 };
1753
1754 static const WCHAR nonexistent_fileW[] = {
1755     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1756 };
1757 static const WCHAR nonexistent_attrW[] = {
1758     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1759 };
1760 static const WCHAR szDocument[] = {
1761     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1762 };
1763
1764 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1765 static WCHAR szdl[] = { 'd','l',0 };
1766 static const WCHAR szvr[] = { 'v','r',0 };
1767 static const WCHAR szlc[] = { 'l','c',0 };
1768 static WCHAR szbs[] = { 'b','s',0 };
1769 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1770 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1771 static const WCHAR szstar[] = { '*',0 };
1772 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1773
1774 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1775 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1776 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1777
1778 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1779 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1780 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1781 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1782                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1783 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1784                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1785
1786 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1787 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1788
1789 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1790                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1791 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1792                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1793                              '!',']',']','>',0};
1794 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1795 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1796
1797 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1798 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1799 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1800
1801 #define expect_bstr_eq_and_free(bstr, expect) { \
1802     BSTR bstrExp = alloc_str_from_narrow(expect); \
1803     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1804     SysFreeString(bstr); \
1805     SysFreeString(bstrExp); \
1806 }
1807
1808 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1809
1810 #define ole_check(expr) { \
1811     HRESULT r = expr; \
1812     ok(r == S_OK, #expr " returned %x\n", r); \
1813 }
1814
1815 #define ole_expect(expr, expect) { \
1816     HRESULT r = expr; \
1817     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1818 }
1819
1820 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1821
1822 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1823 {
1824     void *obj = NULL;
1825     HRESULT hr;
1826
1827     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1828     if (hr != S_OK)
1829         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1830
1831     return obj;
1832 }
1833
1834 #define _create(cls) cls, #cls
1835
1836 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
1837 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1838 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1839 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1840 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1841
1842 static BSTR alloc_str_from_narrow(const char *str)
1843 {
1844     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1845     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1846     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1847     return ret;
1848 }
1849
1850 static BSTR alloced_bstrs[256];
1851 static int alloced_bstrs_count;
1852
1853 static BSTR _bstr_(const char *str)
1854 {
1855     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1856     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1857     return alloced_bstrs[alloced_bstrs_count++];
1858 }
1859
1860 static void free_bstrs(void)
1861 {
1862     int i;
1863     for (i = 0; i < alloced_bstrs_count; i++)
1864         SysFreeString(alloced_bstrs[i]);
1865     alloced_bstrs_count = 0;
1866 }
1867
1868 static VARIANT _variantbstr_(const char *str)
1869 {
1870     VARIANT v;
1871     V_VT(&v) = VT_BSTR;
1872     V_BSTR(&v) = _bstr_(str);
1873     return v;
1874 }
1875
1876 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1877 {
1878     for (;;)
1879     {
1880         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1881         while (*sRight == '\r' || *sRight == '\n') sRight++;
1882         if (*sLeft != *sRight) return FALSE;
1883         if (!*sLeft) return TRUE;
1884         sLeft++;
1885         sRight++;
1886     }
1887 }
1888
1889 static void get_str_for_type(DOMNodeType type, char *buf)
1890 {
1891     switch (type)
1892     {
1893         case NODE_ATTRIBUTE:
1894             strcpy(buf, "A");
1895             break;
1896         case NODE_ELEMENT:
1897             strcpy(buf, "E");
1898             break;
1899         case NODE_DOCUMENT:
1900             strcpy(buf, "D");
1901             break;
1902         case NODE_TEXT:
1903             strcpy(buf, "T");
1904             break;
1905         case NODE_COMMENT:
1906             strcpy(buf, "C");
1907             break;
1908         case NODE_PROCESSING_INSTRUCTION:
1909             strcpy(buf, "P");
1910             break;
1911         default:
1912             wsprintfA(buf, "[%d]", type);
1913     }
1914 }
1915
1916 static int get_node_position(IXMLDOMNode *node)
1917 {
1918     HRESULT r;
1919     int pos = 0;
1920
1921     IXMLDOMNode_AddRef(node);
1922     do
1923     {
1924         IXMLDOMNode *new_node;
1925
1926         pos++;
1927         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1928         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1929         IXMLDOMNode_Release(node);
1930         node = new_node;
1931     } while (r == S_OK);
1932     return pos;
1933 }
1934
1935 static void node_to_string(IXMLDOMNode *node, char *buf)
1936 {
1937     HRESULT r = S_OK;
1938     DOMNodeType type;
1939
1940     if (node == NULL)
1941     {
1942         lstrcpyA(buf, "(null)");
1943         return;
1944     }
1945
1946     IXMLDOMNode_AddRef(node);
1947     while (r == S_OK)
1948     {
1949         IXMLDOMNode *new_node;
1950
1951         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1952         get_str_for_type(type, buf);
1953         buf+=strlen(buf);
1954
1955         if (type == NODE_ATTRIBUTE)
1956         {
1957             BSTR bstr;
1958             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1959             *(buf++) = '\'';
1960             wsprintfA(buf, "%ws", bstr);
1961             buf += strlen(buf);
1962             *(buf++) = '\'';
1963             SysFreeString(bstr);
1964
1965             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1966         }
1967         else
1968         {
1969             r = IXMLDOMNode_get_parentNode(node, &new_node);
1970             wsprintf(buf, "%d", get_node_position(node));
1971             buf += strlen(buf);
1972         }
1973
1974         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1975         IXMLDOMNode_Release(node);
1976         node = new_node;
1977         if (r == S_OK)
1978             *(buf++) = '.';
1979     }
1980
1981     *buf = 0;
1982 }
1983
1984 static char *list_to_string(IXMLDOMNodeList *list)
1985 {
1986     static char buf[4096];
1987     char *pos = buf;
1988     LONG len = 0;
1989     int i;
1990
1991     if (list == NULL)
1992     {
1993         lstrcpyA(buf, "(null)");
1994         return buf;
1995     }
1996     ole_check(IXMLDOMNodeList_get_length(list, &len));
1997     for (i = 0; i < len; i++)
1998     {
1999         IXMLDOMNode *node;
2000         if (i > 0)
2001             *(pos++) = ' ';
2002         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2003         node_to_string(node, pos);
2004         pos += strlen(pos);
2005         IXMLDOMNode_Release(node);
2006     }
2007     *pos = 0;
2008     return buf;
2009 }
2010
2011 #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); }
2012 #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); }
2013
2014 static void test_domdoc( void )
2015 {
2016     HRESULT r, hr;
2017     IXMLDOMDocument *doc;
2018     IXMLDOMParseError *error;
2019     IXMLDOMElement *element = NULL;
2020     IXMLDOMNode *node;
2021     IXMLDOMText *nodetext = NULL;
2022     IXMLDOMComment *node_comment = NULL;
2023     IXMLDOMAttribute *node_attr = NULL;
2024     IXMLDOMNode *nodeChild = NULL;
2025     IXMLDOMProcessingInstruction *nodePI = NULL;
2026     VARIANT_BOOL b;
2027     VARIANT var;
2028     BSTR str;
2029     LONG code, ref;
2030     LONG nLength = 0;
2031     WCHAR buff[100];
2032     const char **ptr;
2033
2034     doc = create_document(&IID_IXMLDOMDocument);
2035     if (!doc) return;
2036
2037 if (0)
2038 {
2039     /* crashes on native */
2040     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2041 }
2042
2043     /* try some stupid things */
2044     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2045     EXPECT_HR(hr, S_FALSE);
2046
2047     b = VARIANT_TRUE;
2048     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2049     EXPECT_HR(hr, S_FALSE);
2050     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2051
2052     /* load document with leading spaces */
2053     ptr = leading_spaces;
2054     while (*ptr)
2055     {
2056         b = VARIANT_TRUE;
2057         V_VT(&var) = VT_BSTR;
2058         V_BSTR(&var) = _bstr_(*ptr);
2059         hr = IXMLDOMDocument_load( doc, var, &b);
2060         EXPECT_HR(hr, S_FALSE);
2061         ok( b == VARIANT_FALSE, "got %x\n", b);
2062         ptr++;
2063     }
2064
2065     /* try to load a document from a nonexistent file */
2066     b = VARIANT_TRUE;
2067     str = SysAllocString( nonexistent_fileW );
2068     VariantInit(&var);
2069     V_VT(&var) = VT_BSTR;
2070     V_BSTR(&var) = str;
2071
2072     r = IXMLDOMDocument_load( doc, var, &b);
2073     ok( r == S_FALSE, "loadXML succeeded\n");
2074     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2075     SysFreeString( str );
2076
2077     /* try load an empty document */
2078     b = VARIANT_TRUE;
2079     str = SysAllocString( szEmpty );
2080     r = IXMLDOMDocument_loadXML( doc, str, &b );
2081     ok( r == S_FALSE, "loadXML succeeded\n");
2082     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2083     SysFreeString( str );
2084
2085     r = IXMLDOMDocument_get_async( doc, &b );
2086     ok( r == S_OK, "get_async failed (%08x)\n", r);
2087     ok( b == VARIANT_TRUE, "Wrong default value\n");
2088
2089     /* check that there's no document element */
2090     element = NULL;
2091     r = IXMLDOMDocument_get_documentElement( doc, &element );
2092     ok( r == S_FALSE, "should be no document element\n");
2093
2094     /* try finding a node */
2095     node = NULL;
2096     str = SysAllocString( szstr1 );
2097     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2098     ok( r == S_FALSE, "ret %08x\n", r );
2099     SysFreeString( str );
2100
2101     b = VARIANT_TRUE;
2102     str = SysAllocString( szIncomplete );
2103     r = IXMLDOMDocument_loadXML( doc, str, &b );
2104     ok( r == S_FALSE, "loadXML succeeded\n");
2105     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2106     SysFreeString( str );
2107
2108     /* check that there's no document element */
2109     element = (IXMLDOMElement*)1;
2110     r = IXMLDOMDocument_get_documentElement( doc, &element );
2111     ok( r == S_FALSE, "should be no document element\n");
2112     ok( element == NULL, "Element should be NULL\n");
2113
2114     /* test for BSTR handling, pass broken BSTR */
2115     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2116     /* just a big length */
2117     *(DWORD*)buff = 0xf0f0;
2118     b = VARIANT_FALSE;
2119     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2120     ok( r == S_OK, "loadXML failed\n");
2121     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2122
2123     /* loadXML ignores the encoding attribute and always expects Unicode */
2124     b = VARIANT_FALSE;
2125     str = SysAllocString( szComplete6 );
2126     r = IXMLDOMDocument_loadXML( doc, str, &b );
2127     ok( r == S_OK, "loadXML failed\n");
2128     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2129     SysFreeString( str );
2130
2131     /* try a BSTR containing a Windows-1252 document */
2132     b = VARIANT_TRUE;
2133     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2134     r = IXMLDOMDocument_loadXML( doc, str, &b );
2135     ok( r == S_FALSE, "loadXML succeeded\n");
2136     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2137     SysFreeString( str );
2138
2139     /* try to load something valid */
2140     b = VARIANT_FALSE;
2141     str = SysAllocString( szComplete1 );
2142     r = IXMLDOMDocument_loadXML( doc, str, &b );
2143     ok( r == S_OK, "loadXML failed\n");
2144     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2145     SysFreeString( str );
2146
2147     /* check if nodename is correct */
2148     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2149     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2150
2151     str = (BSTR)0xdeadbeef;
2152     r = IXMLDOMDocument_get_baseName( doc, &str );
2153     ok ( r == S_FALSE, "got 0x%08x\n", r);
2154     ok (str == NULL, "got %p\n", str);
2155
2156     /* content doesn't matter here */
2157     str = NULL;
2158     r = IXMLDOMDocument_get_nodeName( doc, &str );
2159     ok ( r == S_OK, "get_nodeName wrong code\n");
2160     ok ( str != NULL, "str is null\n");
2161     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2162     SysFreeString( str );
2163
2164     /* test put_text */
2165     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2166     ok( r == E_FAIL, "ret %08x\n", r );
2167
2168     /* check that there's a document element */
2169     element = NULL;
2170     r = IXMLDOMDocument_get_documentElement( doc, &element );
2171     ok( r == S_OK, "should be a document element\n");
2172     if( element )
2173     {
2174         IObjectIdentity *ident;
2175
2176         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2177         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2178
2179         IXMLDOMElement_Release( element );
2180         element = NULL;
2181     }
2182
2183     /* as soon as we call loadXML again, the document element will disappear */
2184     b = 2;
2185     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2186     ok( r == S_FALSE, "loadXML failed\n");
2187     ok( b == 2, "variant modified\n");
2188     r = IXMLDOMDocument_get_documentElement( doc, &element );
2189     ok( r == S_FALSE, "should be no document element\n");
2190
2191     /* try to load something else simple and valid */
2192     b = VARIANT_FALSE;
2193     str = SysAllocString( szComplete3 );
2194     r = IXMLDOMDocument_loadXML( doc, str, &b );
2195     ok( r == S_OK, "loadXML failed\n");
2196     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2197     SysFreeString( str );
2198
2199     /* try something a little more complicated */
2200     b = FALSE;
2201     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2202     ok( r == S_OK, "loadXML failed\n");
2203     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2204
2205     r = IXMLDOMDocument_get_parseError( doc, &error );
2206     ok( r == S_OK, "returns %08x\n", r );
2207
2208     r = IXMLDOMParseError_get_errorCode( error, &code );
2209     ok( r == S_FALSE, "returns %08x\n", r );
2210     ok( code == 0, "code %d\n", code );
2211     IXMLDOMParseError_Release( error );
2212
2213     /* test createTextNode */
2214     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2215     ok( r == S_OK, "returns %08x\n", r );
2216     IXMLDOMText_Release(nodetext);
2217
2218     str = SysAllocString( szOpen );
2219     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2220     ok( r == E_INVALIDARG, "returns %08x\n", r );
2221     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2222     ok( r == S_OK, "returns %08x\n", r );
2223     SysFreeString( str );
2224     if(nodetext)
2225     {
2226         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2227         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2228
2229         /* Text Last Child Checks */
2230         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2231         ok(r == E_INVALIDARG, "ret %08x\n", r );
2232
2233         nodeChild = (IXMLDOMNode*)0x1;
2234         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2235         ok(r == S_FALSE, "ret %08x\n", r );
2236         ok(nodeChild == NULL, "nodeChild not NULL\n");
2237
2238         /* test length property */
2239         r = IXMLDOMText_get_length(nodetext, NULL);
2240         ok(r == E_INVALIDARG, "ret %08x\n", r );
2241
2242         r = IXMLDOMText_get_length(nodetext, &nLength);
2243         ok(r == S_OK, "ret %08x\n", r );
2244         ok(nLength == 4, "expected 4 got %d\n", nLength);
2245
2246         /* put data Tests */
2247         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2248         ok(r == S_OK, "ret %08x\n", r );
2249
2250         /* get data Tests */
2251         r = IXMLDOMText_get_data(nodetext, &str);
2252         ok(r == S_OK, "ret %08x\n", r );
2253         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2254         SysFreeString(str);
2255
2256         /* Confirm XML text is good */
2257         r = IXMLDOMText_get_xml(nodetext, &str);
2258         ok(r == S_OK, "ret %08x\n", r );
2259         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2260         SysFreeString(str);
2261
2262         /* Confirm we get the put_data Text back */
2263         r = IXMLDOMText_get_text(nodetext, &str);
2264         ok(r == S_OK, "ret %08x\n", r );
2265         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2266         SysFreeString(str);
2267
2268         /* test substringData */
2269         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2270         ok(r == E_INVALIDARG, "ret %08x\n", r );
2271
2272         /* test substringData - Invalid offset */
2273         str = (BSTR)&szElement;
2274         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2275         ok(r == E_INVALIDARG, "ret %08x\n", r );
2276         ok( str == NULL, "incorrect string\n");
2277
2278         /* test substringData - Invalid offset */
2279         str = (BSTR)&szElement;
2280         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2281         ok(r == S_FALSE, "ret %08x\n", r );
2282         ok( str == NULL, "incorrect string\n");
2283
2284         /* test substringData - Invalid size */
2285         str = (BSTR)&szElement;
2286         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2287         ok(r == E_INVALIDARG, "ret %08x\n", r );
2288         ok( str == NULL, "incorrect string\n");
2289
2290         /* test substringData - Invalid size */
2291         str = (BSTR)&szElement;
2292         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2293         ok(r == S_FALSE, "ret %08x\n", r );
2294         ok( str == NULL, "incorrect string\n");
2295
2296         /* test substringData - Start of string */
2297         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2298         ok(r == S_OK, "ret %08x\n", r );
2299         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2300         SysFreeString(str);
2301
2302         /* test substringData - Middle of string */
2303         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2304         ok(r == S_OK, "ret %08x\n", r );
2305         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2306         SysFreeString(str);
2307
2308         /* test substringData - End of string */
2309         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2310         ok(r == S_OK, "ret %08x\n", r );
2311         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2312         SysFreeString(str);
2313
2314         /* test appendData */
2315         r = IXMLDOMText_appendData(nodetext, NULL);
2316         ok(r == S_OK, "ret %08x\n", r );
2317
2318         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2319         ok(r == S_OK, "ret %08x\n", r );
2320
2321         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2322         ok(r == S_OK, "ret %08x\n", r );
2323
2324         r = IXMLDOMText_get_text(nodetext, &str);
2325         ok(r == S_OK, "ret %08x\n", r );
2326         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2327         SysFreeString(str);
2328
2329         /* test insertData */
2330         str = SysAllocStringLen(NULL, 0);
2331         r = IXMLDOMText_insertData(nodetext, -1, str);
2332         ok(r == S_OK, "ret %08x\n", r );
2333
2334         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2335         ok(r == S_OK, "ret %08x\n", r );
2336
2337         r = IXMLDOMText_insertData(nodetext, 1000, str);
2338         ok(r == S_OK, "ret %08x\n", r );
2339
2340         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2341         ok(r == S_OK, "ret %08x\n", r );
2342
2343         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2344         ok(r == S_OK, "ret %08x\n", r );
2345
2346         r = IXMLDOMText_insertData(nodetext, 0, str);
2347         ok(r == S_OK, "ret %08x\n", r );
2348         SysFreeString(str);
2349
2350         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2351         ok(r == E_INVALIDARG, "ret %08x\n", r );
2352
2353         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2354         ok(r == E_INVALIDARG, "ret %08x\n", r );
2355
2356         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2357         ok(r == S_OK, "ret %08x\n", r );
2358
2359         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2360         ok(r == S_OK, "ret %08x\n", r );
2361
2362         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2363         ok(r == S_OK, "ret %08x\n", r );
2364
2365         r = IXMLDOMText_get_text(nodetext, &str);
2366         ok(r == S_OK, "ret %08x\n", r );
2367         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2368         SysFreeString(str);
2369
2370         /* delete data */
2371         /* invalid arguments */
2372         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2373         ok(r == E_INVALIDARG, "ret %08x\n", r );
2374
2375         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2376         ok(r == S_OK, "ret %08x\n", r );
2377
2378         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2379         ok(r == E_INVALIDARG, "ret %08x\n", r );
2380
2381         r = IXMLDOMText_get_length(nodetext, &nLength);
2382         ok(r == S_OK, "ret %08x\n", r );
2383         ok(nLength == 43, "expected 43 got %d\n", nLength);
2384
2385         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2386         ok(r == S_OK, "ret %08x\n", r );
2387
2388         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2389         ok(r == E_INVALIDARG, "ret %08x\n", r );
2390
2391         /* delete from start */
2392         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2393         ok(r == S_OK, "ret %08x\n", r );
2394
2395         r = IXMLDOMText_get_length(nodetext, &nLength);
2396         ok(r == S_OK, "ret %08x\n", r );
2397         ok(nLength == 38, "expected 38 got %d\n", nLength);
2398
2399         r = IXMLDOMText_get_text(nodetext, &str);
2400         ok(r == S_OK, "ret %08x\n", r );
2401         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2402         SysFreeString(str);
2403
2404         /* delete from end */
2405         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2406         ok(r == S_OK, "ret %08x\n", r );
2407
2408         r = IXMLDOMText_get_length(nodetext, &nLength);
2409         ok(r == S_OK, "ret %08x\n", r );
2410         ok(nLength == 35, "expected 35 got %d\n", nLength);
2411
2412         r = IXMLDOMText_get_text(nodetext, &str);
2413         ok(r == S_OK, "ret %08x\n", r );
2414         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2415         SysFreeString(str);
2416
2417         /* delete from inside */
2418         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2419         ok(r == S_OK, "ret %08x\n", r );
2420
2421         r = IXMLDOMText_get_length(nodetext, &nLength);
2422         ok(r == S_OK, "ret %08x\n", r );
2423         ok(nLength == 2, "expected 2 got %d\n", nLength);
2424
2425         r = IXMLDOMText_get_text(nodetext, &str);
2426         ok(r == S_OK, "ret %08x\n", r );
2427         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2428         SysFreeString(str);
2429
2430         /* delete whole data ... */
2431         r = IXMLDOMText_get_length(nodetext, &nLength);
2432         ok(r == S_OK, "ret %08x\n", r );
2433
2434         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2435         ok(r == S_OK, "ret %08x\n", r );
2436         /* ... and try again with empty string */
2437         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2438         ok(r == S_OK, "ret %08x\n", r );
2439
2440         /* test put_data */
2441         V_VT(&var) = VT_BSTR;
2442         V_BSTR(&var) = SysAllocString(szstr1);
2443         r = IXMLDOMText_put_nodeValue(nodetext, var);
2444         ok(r == S_OK, "ret %08x\n", r );
2445         VariantClear(&var);
2446
2447         r = IXMLDOMText_get_text(nodetext, &str);
2448         ok(r == S_OK, "ret %08x\n", r );
2449         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2450         SysFreeString(str);
2451
2452         /* test put_data */
2453         V_VT(&var) = VT_I4;
2454         V_I4(&var) = 99;
2455         r = IXMLDOMText_put_nodeValue(nodetext, var);
2456         ok(r == S_OK, "ret %08x\n", r );
2457         VariantClear(&var);
2458
2459         r = IXMLDOMText_get_text(nodetext, &str);
2460         ok(r == S_OK, "ret %08x\n", r );
2461         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2462         SysFreeString(str);
2463
2464         /* ::replaceData() */
2465         V_VT(&var) = VT_BSTR;
2466         V_BSTR(&var) = SysAllocString(szstr1);
2467         r = IXMLDOMText_put_nodeValue(nodetext, var);
2468         ok(r == S_OK, "ret %08x\n", r );
2469         VariantClear(&var);
2470
2471         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2472         ok(r == E_INVALIDARG, "ret %08x\n", r );
2473         r = IXMLDOMText_get_text(nodetext, &str);
2474         ok(r == S_OK, "ret %08x\n", r );
2475         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2476         SysFreeString(str);
2477
2478         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2479         ok(r == S_OK, "ret %08x\n", r );
2480         r = IXMLDOMText_get_text(nodetext, &str);
2481         ok(r == S_OK, "ret %08x\n", r );
2482         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2483         SysFreeString(str);
2484
2485         /* NULL pointer means delete */
2486         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2487         ok(r == S_OK, "ret %08x\n", r );
2488         r = IXMLDOMText_get_text(nodetext, &str);
2489         ok(r == S_OK, "ret %08x\n", r );
2490         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2491         SysFreeString(str);
2492
2493         /* empty string means delete */
2494         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2495         ok(r == S_OK, "ret %08x\n", r );
2496         r = IXMLDOMText_get_text(nodetext, &str);
2497         ok(r == S_OK, "ret %08x\n", r );
2498         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2499         SysFreeString(str);
2500
2501         /* zero count means insert */
2502         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2503         ok(r == S_OK, "ret %08x\n", r );
2504         r = IXMLDOMText_get_text(nodetext, &str);
2505         ok(r == S_OK, "ret %08x\n", r );
2506         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2507         SysFreeString(str);
2508
2509         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2510         ok(r == S_OK, "ret %08x\n", r );
2511
2512         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2513         ok(r == S_OK, "ret %08x\n", r );
2514         r = IXMLDOMText_get_text(nodetext, &str);
2515         ok(r == S_OK, "ret %08x\n", r );
2516         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2517         SysFreeString(str);
2518
2519         /* nonempty string, count greater than its length */
2520         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2521         ok(r == S_OK, "ret %08x\n", r );
2522         r = IXMLDOMText_get_text(nodetext, &str);
2523         ok(r == S_OK, "ret %08x\n", r );
2524         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2525         SysFreeString(str);
2526
2527         /* nonempty string, count less than its length */
2528         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2529         ok(r == S_OK, "ret %08x\n", r );
2530         r = IXMLDOMText_get_text(nodetext, &str);
2531         ok(r == S_OK, "ret %08x\n", r );
2532         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2533         SysFreeString(str);
2534
2535         IXMLDOMText_Release( nodetext );
2536     }
2537
2538     /* test Create Comment */
2539     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2540     ok( r == E_INVALIDARG, "returns %08x\n", r );
2541     node_comment = (IXMLDOMComment*)0x1;
2542
2543     /* empty comment */
2544     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2545     ok( r == S_OK, "returns %08x\n", r );
2546     str = (BSTR)0x1;
2547     r = IXMLDOMComment_get_data(node_comment, &str);
2548     ok( r == S_OK, "returns %08x\n", r );
2549     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2550     IXMLDOMComment_Release(node_comment);
2551     SysFreeString(str);
2552
2553     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2554     ok( r == S_OK, "returns %08x\n", r );
2555     str = (BSTR)0x1;
2556     r = IXMLDOMComment_get_data(node_comment, &str);
2557     ok( r == S_OK, "returns %08x\n", r );
2558     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2559     IXMLDOMComment_Release(node_comment);
2560     SysFreeString(str);
2561
2562     str = SysAllocString(szComment);
2563     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2564     SysFreeString(str);
2565     ok( r == S_OK, "returns %08x\n", r );
2566     if(node_comment)
2567     {
2568         /* Last Child Checks */
2569         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2570         ok(r == E_INVALIDARG, "ret %08x\n", r );
2571
2572         nodeChild = (IXMLDOMNode*)0x1;
2573         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2574         ok(r == S_FALSE, "ret %08x\n", r );
2575         ok(nodeChild == NULL, "pLastChild not NULL\n");
2576
2577         /* baseName */
2578         str = (BSTR)0xdeadbeef;
2579         IXMLDOMComment_get_baseName(node_comment, &str);
2580         ok(r == S_FALSE, "ret %08x\n", r );
2581         ok(str == NULL, "Expected NULL\n");
2582
2583         IXMLDOMComment_Release( node_comment );
2584     }
2585
2586     /* test Create Attribute */
2587     str = SysAllocString(szAttribute);
2588     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2589     ok( r == E_INVALIDARG, "returns %08x\n", r );
2590     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2591     ok( r == S_OK, "returns %08x\n", r );
2592     IXMLDOMText_Release( node_attr);
2593     SysFreeString(str);
2594
2595     /* test Processing Instruction */
2596     str = SysAllocStringLen(NULL, 0);
2597     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2598     ok( r == E_INVALIDARG, "returns %08x\n", r );
2599     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2600     ok( r == E_FAIL, "returns %08x\n", r );
2601     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2602     ok( r == E_FAIL, "returns %08x\n", r );
2603     SysFreeString(str);
2604
2605     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2606     ok( r == S_OK, "returns %08x\n", r );
2607     if(nodePI)
2608     {
2609         /* Last Child Checks */
2610         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2611         ok(r == E_INVALIDARG, "ret %08x\n", r );
2612
2613         nodeChild = (IXMLDOMNode*)0x1;
2614         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2615         ok(r == S_FALSE, "ret %08x\n", r );
2616         ok(nodeChild == NULL, "nodeChild not NULL\n");
2617
2618         /* test nodeName */
2619         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2620         ok(r == S_OK, "ret %08x\n", r );
2621         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2622         SysFreeString(str);
2623
2624         /* test baseName */
2625         str = (BSTR)0x1;
2626         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2627         ok(r == S_OK, "ret %08x\n", r );
2628         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2629         SysFreeString(str);
2630
2631         /* test Target */
2632         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2633         ok(r == S_OK, "ret %08x\n", r );
2634         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2635         SysFreeString(str);
2636
2637         /* test get_nodeValue */
2638         r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
2639         ok(r == S_OK, "ret %08x\n", r );
2640         ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2641         VariantClear(&var);
2642
2643         /* test get_data */
2644         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2645         ok(r == S_OK, "ret %08x\n", r );
2646         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2647         SysFreeString(str);
2648
2649         /* test put_data */
2650         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2651         ok(r == E_FAIL, "ret %08x\n", r );
2652
2653         /* test put_data */
2654         V_VT(&var) = VT_BSTR;
2655         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2656         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2657         ok(r == E_FAIL, "ret %08x\n", r );
2658         VariantClear(&var);
2659
2660         /* test get nodeName */
2661         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2662         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2663         ok(r == S_OK, "ret %08x\n", r );
2664         SysFreeString(str);
2665
2666         IXMLDOMProcessingInstruction_Release(nodePI);
2667     }
2668
2669     ref = IXMLDOMDocument_Release( doc );
2670     ok( ref == 0, "got %d\n", ref);
2671
2672     free_bstrs();
2673 }
2674
2675 static void test_persiststreaminit(void)
2676 {
2677     IXMLDOMDocument *doc;
2678     IPersistStreamInit *streaminit;
2679     HRESULT hr;
2680
2681     doc = create_document(&IID_IXMLDOMDocument);
2682     if (!doc) return;
2683
2684     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2685     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2686
2687     hr = IPersistStreamInit_InitNew(streaminit);
2688     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2689
2690     IXMLDOMDocument_Release(doc);
2691 }
2692
2693 static void test_domnode( void )
2694 {
2695     HRESULT r;
2696     IXMLDOMDocument *doc, *owner = NULL;
2697     IXMLDOMElement *element = NULL;
2698     IXMLDOMNamedNodeMap *map = NULL;
2699     IXMLDOMNode *node = NULL, *next = NULL;
2700     IXMLDOMNodeList *list = NULL;
2701     IXMLDOMAttribute *attr = NULL;
2702     DOMNodeType type = NODE_INVALID;
2703     VARIANT_BOOL b;
2704     BSTR str;
2705     VARIANT var;
2706     LONG count;
2707
2708     doc = create_document(&IID_IXMLDOMDocument);
2709     if (!doc) return;
2710
2711     b = FALSE;
2712     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2713     ok( r == S_OK, "loadXML failed\n");
2714     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2715
2716     EXPECT_CHILDREN(doc);
2717
2718     r = IXMLDOMDocument_get_documentElement( doc, &element );
2719     ok( r == S_OK, "should be a document element\n");
2720     ok( element != NULL, "should be an element\n");
2721
2722     VariantInit(&var);
2723     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2724
2725     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2726     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2727
2728     r = IXMLDOMNode_get_nodeValue( doc, &var );
2729     ok( r == S_FALSE, "nextNode returned wrong code\n");
2730     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2731     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2732
2733     if (element)
2734     {
2735         owner = NULL;
2736         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2737         ok( r == S_OK, "get_ownerDocument return code\n");
2738         ok( owner != doc, "get_ownerDocument return\n");
2739         IXMLDOMDocument_Release(owner);
2740
2741         type = NODE_INVALID;
2742         r = IXMLDOMNode_get_nodeType( element, &type);
2743         ok( r == S_OK, "got %08x\n", r);
2744         ok( type == NODE_ELEMENT, "node not an element\n");
2745
2746         str = NULL;
2747         r = IXMLDOMNode_get_baseName( element, &str );
2748         ok( r == S_OK, "get_baseName returned wrong code\n");
2749         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2750         SysFreeString(str);
2751
2752         /* check if nodename is correct */
2753         r = IXMLDOMElement_get_nodeName( element, NULL );
2754         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2755
2756         /* content doesn't matter here */
2757         str = NULL;
2758         r = IXMLDOMElement_get_nodeName( element, &str );
2759         ok ( r == S_OK, "get_nodeName wrong code\n");
2760         ok ( str != NULL, "str is null\n");
2761         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2762         SysFreeString( str );
2763
2764         str = SysAllocString( nonexistent_fileW );
2765         V_VT(&var) = VT_I4;
2766         V_I4(&var) = 0x1234;
2767         r = IXMLDOMElement_getAttribute( element, str, &var );
2768         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2769         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2770         VariantClear(&var);
2771
2772         str = SysAllocString( szdl );   
2773         V_VT(&var) = VT_I4;
2774         V_I4(&var) = 0x1234;
2775         r = IXMLDOMElement_getAttribute( element, str, &var );
2776         ok( r == S_OK, "getAttribute ret %08x\n", r );
2777         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2778         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2779         VariantClear( &var );
2780
2781         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2782         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2783
2784         r = IXMLDOMElement_getAttribute( element, str, NULL );
2785         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2786
2787         attr = NULL;
2788         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2789         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2790         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2791         if (attr)
2792         {
2793             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2794             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2795
2796             /* attribute doesn't have a parent in msxml interpretation */
2797             node = (IXMLDOMNode*)0xdeadbeef;
2798             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2799             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2800             ok( node == NULL, "Expected NULL, got %p\n", node );
2801
2802             IXMLDOMAttribute_Release(attr);
2803         }
2804
2805         SysFreeString( str );
2806
2807         r = IXMLDOMElement_get_attributes( element, &map );
2808         ok( r == S_OK, "get_attributes returned wrong code\n");
2809         ok( map != NULL, "should be attributes\n");
2810
2811         EXPECT_CHILDREN(element);
2812     }
2813     else
2814         ok( FALSE, "no element\n");
2815
2816     if (map)
2817     {
2818         ISupportErrorInfo *support_error;
2819         r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (void**)&support_error );
2820         ok( r == S_OK, "ret %08x\n", r );
2821
2822         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
2823         todo_wine EXPECT_HR(r, S_OK);
2824         ISupportErrorInfo_Release( support_error );
2825
2826         str = SysAllocString( szdl );
2827         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2828         ok( r == S_OK, "getNamedItem returned wrong code\n");
2829         ok( node != NULL, "should be attributes\n");
2830         IXMLDOMNode_Release(node);
2831         SysFreeString( str );
2832
2833         str = SysAllocString( szdl );
2834         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2835         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2836         SysFreeString( str );
2837
2838         /* something that isn't in complete4A */
2839         str = SysAllocString( szOpen );
2840         node = (IXMLDOMNode *) 1;
2841         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2842         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2843         ok( node == NULL, "getNamedItem should have returned NULL\n");
2844         SysFreeString( str );
2845
2846         /* test indexed access of attributes */
2847         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2848         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2849
2850         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2851         ok ( r == S_OK, "get_length wrong code\n");
2852         ok ( count == 1, "get_length != 1\n");
2853
2854         node = NULL;
2855         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2856         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2857         ok ( node == NULL, "there is no node\n");
2858
2859         node = NULL;
2860         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2861         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2862         ok ( node == NULL, "there is no attribute\n");
2863
2864         node = NULL;
2865         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2866         ok ( r == S_OK, "get_item (0) wrong code\n");
2867         ok ( node != NULL, "should be attribute\n");
2868
2869         r = IXMLDOMNode_get_nodeName( node, NULL );
2870         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2871
2872         /* content doesn't matter here */
2873         str = NULL;
2874         r = IXMLDOMNode_get_nodeName( node, &str );
2875         ok ( r == S_OK, "get_nodeName wrong code\n");
2876         ok ( str != NULL, "str is null\n");
2877         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2878         SysFreeString( str );
2879         IXMLDOMNode_Release( node );
2880
2881         /* test sequential access of attributes */
2882         node = NULL;
2883         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2884         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2885         ok ( node != NULL, "nextNode, should be attribute\n");
2886         IXMLDOMNode_Release( node );
2887
2888         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2889         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2890         ok ( node == NULL, "nextNode, there is no attribute\n");
2891
2892         r = IXMLDOMNamedNodeMap_reset( map );
2893         ok ( r == S_OK, "reset should return S_OK\n");
2894
2895         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2896         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2897         ok ( node != NULL, "nextNode, should be attribute\n");
2898     }
2899     else
2900         ok( FALSE, "no map\n");
2901
2902     if (node)
2903     {
2904         type = NODE_INVALID;
2905         r = IXMLDOMNode_get_nodeType( node, &type);
2906         ok( r == S_OK, "getNamedItem returned wrong code\n");
2907         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2908
2909         str = NULL;
2910         r = IXMLDOMNode_get_baseName( node, NULL );
2911         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2912
2913         str = NULL;
2914         r = IXMLDOMNode_get_baseName( node, &str );
2915         ok( r == S_OK, "get_baseName returned wrong code\n");
2916         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2917         SysFreeString( str );
2918
2919         r = IXMLDOMNode_get_nodeValue( node, &var );
2920         ok( r == S_OK, "returns %08x\n", r );
2921         ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
2922         ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
2923         VariantClear(&var);
2924
2925         r = IXMLDOMNode_get_childNodes( node, NULL );
2926         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2927
2928         r = IXMLDOMNode_get_childNodes( node, &list );
2929         ok( r == S_OK, "get_childNodes returned wrong code\n");
2930
2931         if (list)
2932         {
2933             r = IXMLDOMNodeList_nextNode( list, &next );
2934             ok( r == S_OK, "nextNode returned wrong code\n");
2935         }
2936         else
2937             ok( FALSE, "no childlist\n");
2938
2939         if (next)
2940         {
2941             EXPECT_NO_CHILDREN(next);
2942
2943             type = NODE_INVALID;
2944             r = IXMLDOMNode_get_nodeType( next, &type);
2945             ok( r == S_OK, "getNamedItem returned wrong code\n");
2946             ok( type == NODE_TEXT, "node not text\n");
2947
2948             str = (BSTR) 1;
2949             r = IXMLDOMNode_get_baseName( next, &str );
2950             ok( r == S_FALSE, "get_baseName returned wrong code\n");
2951             ok( str == NULL, "basename was wrong\n");
2952             SysFreeString(str);
2953         }
2954         else
2955             ok( FALSE, "no next\n");
2956
2957         if (next)
2958             IXMLDOMNode_Release( next );
2959         next = NULL;
2960         if (list)
2961             IXMLDOMNodeList_Release( list );
2962         list = NULL;
2963         if (node)
2964             IXMLDOMNode_Release( node );
2965     }
2966     else
2967         ok( FALSE, "no node\n");
2968     node = NULL;
2969
2970     if (map)
2971         IXMLDOMNamedNodeMap_Release( map );
2972
2973     /* now traverse the tree from the root element */
2974     if (element)
2975     {
2976         r = IXMLDOMNode_get_childNodes( element, &list );
2977         ok( r == S_OK, "get_childNodes returned wrong code\n");
2978
2979         /* using get_item for child list doesn't advance the position */
2980         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2981         expect_node(node, "E2.E2.D1");
2982         IXMLDOMNode_Release(node);
2983         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2984         expect_node(node, "E1.E2.D1");
2985         IXMLDOMNode_Release(node);
2986         ole_check(IXMLDOMNodeList_reset(list));
2987
2988         IXMLDOMNodeList_AddRef(list);
2989         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2990         ole_check(IXMLDOMNodeList_reset(list));
2991
2992         node = (void*)0xdeadbeef;
2993         str = SysAllocString(szdl);
2994         r = IXMLDOMNode_selectSingleNode( element, str, &node );
2995         SysFreeString(str);
2996         ok( r == S_FALSE, "ret %08x\n", r );
2997         ok( node == NULL, "node %p\n", node );
2998
2999         str = SysAllocString(szbs);
3000         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3001         SysFreeString(str);
3002         ok( r == S_OK, "ret %08x\n", r );
3003         r = IXMLDOMNode_Release( node );
3004         ok( r == 0, "ret %08x\n", r );
3005     }
3006     else
3007         ok( FALSE, "no element\n");
3008
3009     if (list)
3010     {
3011         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3012         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3013
3014         r = IXMLDOMNodeList_get_length(list, NULL);
3015         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3016
3017         r = IXMLDOMNodeList_get_length( list, &count );
3018         ok( r == S_OK, "get_length returns %08x\n", r );
3019         ok( count == 4, "get_length got %d\n", count );
3020
3021         r = IXMLDOMNodeList_nextNode(list, NULL);
3022         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3023
3024         r = IXMLDOMNodeList_nextNode( list, &node );
3025         ok( r == S_OK, "nextNode returned wrong code\n");
3026     }
3027     else
3028         ok( FALSE, "no list\n");
3029
3030     if (node)
3031     {
3032         type = NODE_INVALID;
3033         r = IXMLDOMNode_get_nodeType( node, &type);
3034         ok( r == S_OK, "getNamedItem returned wrong code\n");
3035         ok( type == NODE_ELEMENT, "node not text\n");
3036
3037         VariantInit(&var);
3038         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
3039         r = IXMLDOMNode_get_nodeValue( node, &var );
3040         ok( r == S_FALSE, "nextNode returned wrong code\n");
3041         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
3042         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
3043
3044         r = IXMLDOMNode_hasChildNodes( node, NULL );
3045         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3046
3047         EXPECT_CHILDREN(node);
3048
3049         str = NULL;
3050         r = IXMLDOMNode_get_baseName( node, &str );
3051         ok( r == S_OK, "get_baseName returned wrong code\n");
3052         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3053         SysFreeString(str);
3054     }
3055     else
3056         ok( FALSE, "no node\n");
3057
3058     if (node)
3059         IXMLDOMNode_Release( node );
3060     if (list)
3061         IXMLDOMNodeList_Release( list );
3062     if (element)
3063         IXMLDOMElement_Release( element );
3064
3065     b = FALSE;
3066     str = SysAllocString( szComplete5 );
3067     r = IXMLDOMDocument_loadXML( doc, str, &b );
3068     ok( r == S_OK, "loadXML failed\n");
3069     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3070     SysFreeString( str );
3071
3072     EXPECT_CHILDREN(doc);
3073
3074     r = IXMLDOMDocument_get_documentElement( doc, &element );
3075     ok( r == S_OK, "should be a document element\n");
3076     ok( element != NULL, "should be an element\n");
3077
3078     if (element)
3079     {
3080         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3081         BSTR tag = NULL;
3082
3083         /* check if the tag is correct */
3084         r = IXMLDOMElement_get_tagName( element, &tag );
3085         ok( r == S_OK, "couldn't get tag name\n");
3086         ok( tag != NULL, "tag was null\n");
3087         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3088         SysFreeString( tag );
3089     }
3090
3091     if (element)
3092         IXMLDOMElement_Release( element );
3093     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3094
3095     free_bstrs();
3096 }
3097
3098 static void test_refs(void)
3099 {
3100     HRESULT r;
3101     VARIANT_BOOL b;
3102     IXMLDOMDocument *doc;
3103     IXMLDOMElement *element = NULL;
3104     IXMLDOMNode *node = NULL, *node2;
3105     IXMLDOMNodeList *node_list = NULL;
3106     LONG ref;
3107     IUnknown *unk, *unk2;
3108
3109     doc = create_document(&IID_IXMLDOMDocument);
3110     if (!doc) return;
3111
3112     EXPECT_REF(doc, 1);
3113     ref = IXMLDOMDocument_Release(doc);
3114     ok( ref == 0, "ref %d\n", ref);
3115
3116     doc = create_document(&IID_IXMLDOMDocument);
3117     if (!doc) return;
3118
3119     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3120     ok( r == S_OK, "loadXML failed\n");
3121     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3122
3123     EXPECT_REF(doc, 1);
3124     IXMLDOMDocument_AddRef( doc );
3125     EXPECT_REF(doc, 2);
3126     IXMLDOMDocument_AddRef( doc );
3127     EXPECT_REF(doc, 3);
3128
3129     IXMLDOMDocument_Release( doc );
3130     IXMLDOMDocument_Release( doc );
3131
3132     r = IXMLDOMDocument_get_documentElement( doc, &element );
3133     ok( r == S_OK, "should be a document element\n");
3134     ok( element != NULL, "should be an element\n");
3135
3136     EXPECT_REF(doc, 1);
3137     todo_wine EXPECT_REF(element, 2);
3138
3139     IXMLDOMElement_AddRef(element);
3140     todo_wine EXPECT_REF(element, 3);
3141     IXMLDOMElement_Release(element);
3142
3143     r = IXMLDOMElement_get_childNodes( element, &node_list );
3144     ok( r == S_OK, "rets %08x\n", r);
3145
3146     todo_wine EXPECT_REF(element, 2);
3147     EXPECT_REF(node_list, 1);
3148
3149     IXMLDOMNodeList_get_item( node_list, 0, &node );
3150     ok( r == S_OK, "rets %08x\n", r);
3151     EXPECT_REF(node_list, 1);
3152     EXPECT_REF(node, 1);
3153
3154     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3155     ok( r == S_OK, "rets %08x\n", r);
3156     EXPECT_REF(node_list, 1);
3157     EXPECT_REF(node2, 1);
3158
3159     ref = IXMLDOMNode_Release( node );
3160     ok( ref == 0, "ref %d\n", ref );
3161     ref = IXMLDOMNode_Release( node2 );
3162     ok( ref == 0, "ref %d\n", ref );
3163
3164     ref = IXMLDOMNodeList_Release( node_list );
3165     ok( ref == 0, "ref %d\n", ref );
3166
3167     ok( node != node2, "node %p node2 %p\n", node, node2 );
3168
3169     ref = IXMLDOMDocument_Release( doc );
3170     ok( ref == 0, "ref %d\n", ref );
3171
3172     todo_wine EXPECT_REF(element, 2);
3173
3174     /* IUnknown must be unique however we obtain it */
3175     r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (void**)&unk );
3176     ok( r == S_OK, "rets %08x\n", r );
3177     EXPECT_REF(element, 2);
3178     r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (void**)&node );
3179     ok( r == S_OK, "rets %08x\n", r );
3180     todo_wine EXPECT_REF(element, 2);
3181     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk2 );
3182     ok( r == S_OK, "rets %08x\n", r );
3183     todo_wine EXPECT_REF(element, 2);
3184     ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
3185     todo_wine ok( element != (void*)node, "node %p element %p\n", node, element );
3186
3187     IUnknown_Release( unk2 );
3188     IUnknown_Release( unk );
3189     IXMLDOMNode_Release( node );
3190     todo_wine EXPECT_REF(element, 2);
3191
3192     IXMLDOMElement_Release( element );
3193
3194     free_bstrs();
3195 }
3196
3197 static void test_create(void)
3198 {
3199     static const WCHAR szOne[] = {'1',0};
3200     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3201     HRESULT r;
3202     VARIANT var;
3203     BSTR str, name;
3204     IXMLDOMDocument *doc;
3205     IXMLDOMElement *element;
3206     IXMLDOMComment *comment;
3207     IXMLDOMText *text;
3208     IXMLDOMCDATASection *cdata;
3209     IXMLDOMNode *root, *node, *child;
3210     IXMLDOMNamedNodeMap *attr_map;
3211     IUnknown *unk;
3212     LONG ref;
3213     LONG num;
3214
3215     doc = create_document(&IID_IXMLDOMDocument);
3216     if (!doc) return;
3217
3218     EXPECT_REF(doc, 1);
3219
3220     /* types not supported for creation */
3221     V_VT(&var) = VT_I1;
3222     V_I1(&var) = NODE_DOCUMENT;
3223     node = (IXMLDOMNode*)0x1;
3224     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3225     ok( r == E_INVALIDARG, "returns %08x\n", r );
3226     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3227
3228     V_VT(&var) = VT_I1;
3229     V_I1(&var) = NODE_DOCUMENT_TYPE;
3230     node = (IXMLDOMNode*)0x1;
3231     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3232     ok( r == E_INVALIDARG, "returns %08x\n", r );
3233     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3234
3235     V_VT(&var) = VT_I1;
3236     V_I1(&var) = NODE_ENTITY;
3237     node = (IXMLDOMNode*)0x1;
3238     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3239     ok( r == E_INVALIDARG, "returns %08x\n", r );
3240     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3241
3242     V_VT(&var) = VT_I1;
3243     V_I1(&var) = NODE_NOTATION;
3244     node = (IXMLDOMNode*)0x1;
3245     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3246     ok( r == E_INVALIDARG, "returns %08x\n", r );
3247     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3248
3249     /* NODE_COMMENT */
3250     V_VT(&var) = VT_I1;
3251     V_I1(&var) = NODE_COMMENT;
3252     node = NULL;
3253     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3254     ok( r == S_OK, "returns %08x\n", r );
3255     ok( node != NULL, "\n");
3256
3257     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3258     ok( r == S_OK, "returns %08x\n", r );
3259     IXMLDOMNode_Release(node);
3260
3261     str = NULL;
3262     r = IXMLDOMComment_get_data(comment, &str);
3263     ok( r == S_OK, "returns %08x\n", r );
3264     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3265     IXMLDOMComment_Release(comment);
3266     SysFreeString(str);
3267
3268     node = (IXMLDOMNode*)0x1;
3269     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3270     ok( r == S_OK, "returns %08x\n", r );
3271
3272     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3273     ok( r == S_OK, "returns %08x\n", r );
3274     IXMLDOMNode_Release(node);
3275
3276     str = NULL;
3277     r = IXMLDOMComment_get_data(comment, &str);
3278     ok( r == S_OK, "returns %08x\n", r );
3279     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3280     IXMLDOMComment_Release(comment);
3281     SysFreeString(str);
3282
3283     node = (IXMLDOMNode*)0x1;
3284     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3285     ok( r == S_OK, "returns %08x\n", r );
3286
3287     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3288     ok( r == S_OK, "returns %08x\n", r );
3289     IXMLDOMNode_Release(node);
3290
3291     str = NULL;
3292     r = IXMLDOMComment_get_data(comment, &str);
3293     ok( r == S_OK, "returns %08x\n", r );
3294     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3295     IXMLDOMComment_Release(comment);
3296     SysFreeString(str);
3297
3298     /* NODE_TEXT */
3299     V_VT(&var) = VT_I1;
3300     V_I1(&var) = NODE_TEXT;
3301     node = NULL;
3302     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3303     ok( r == S_OK, "returns %08x\n", r );
3304     ok( node != NULL, "\n");
3305
3306     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3307     ok( r == S_OK, "returns %08x\n", r );
3308     IXMLDOMNode_Release(node);
3309
3310     str = NULL;
3311     r = IXMLDOMText_get_data(text, &str);
3312     ok( r == S_OK, "returns %08x\n", r );
3313     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3314     IXMLDOMText_Release(text);
3315     SysFreeString(str);
3316
3317     node = (IXMLDOMNode*)0x1;
3318     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3319     ok( r == S_OK, "returns %08x\n", r );
3320
3321     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3322     ok( r == S_OK, "returns %08x\n", r );
3323     IXMLDOMNode_Release(node);
3324
3325     str = NULL;
3326     r = IXMLDOMText_get_data(text, &str);
3327     ok( r == S_OK, "returns %08x\n", r );
3328     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3329     IXMLDOMText_Release(text);
3330     SysFreeString(str);
3331
3332     node = (IXMLDOMNode*)0x1;
3333     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3334     ok( r == S_OK, "returns %08x\n", r );
3335
3336     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3337     ok( r == S_OK, "returns %08x\n", r );
3338     IXMLDOMNode_Release(node);
3339
3340     str = NULL;
3341     r = IXMLDOMText_get_data(text, &str);
3342     ok( r == S_OK, "returns %08x\n", r );
3343     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3344     IXMLDOMText_Release(text);
3345     SysFreeString(str);
3346
3347     /* NODE_CDATA_SECTION */
3348     V_VT(&var) = VT_I1;
3349     V_I1(&var) = NODE_CDATA_SECTION;
3350     node = NULL;
3351     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3352     ok( r == S_OK, "returns %08x\n", r );
3353     ok( node != NULL, "\n");
3354
3355     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3356     ok( r == S_OK, "returns %08x\n", r );
3357     IXMLDOMNode_Release(node);
3358
3359     str = NULL;
3360     r = IXMLDOMCDATASection_get_data(cdata, &str);
3361     ok( r == S_OK, "returns %08x\n", r );
3362     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3363     IXMLDOMCDATASection_Release(cdata);
3364     SysFreeString(str);
3365
3366     node = (IXMLDOMNode*)0x1;
3367     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3368     ok( r == S_OK, "returns %08x\n", r );
3369
3370     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3371     ok( r == S_OK, "returns %08x\n", r );
3372     IXMLDOMNode_Release(node);
3373
3374     str = NULL;
3375     r = IXMLDOMCDATASection_get_data(cdata, &str);
3376     ok( r == S_OK, "returns %08x\n", r );
3377     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3378     IXMLDOMCDATASection_Release(cdata);
3379     SysFreeString(str);
3380
3381     node = (IXMLDOMNode*)0x1;
3382     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3383     ok( r == S_OK, "returns %08x\n", r );
3384
3385     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3386     ok( r == S_OK, "returns %08x\n", r );
3387     IXMLDOMNode_Release(node);
3388
3389     str = NULL;
3390     r = IXMLDOMCDATASection_get_data(cdata, &str);
3391     ok( r == S_OK, "returns %08x\n", r );
3392     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3393     IXMLDOMCDATASection_Release(cdata);
3394     SysFreeString(str);
3395
3396     /* NODE_ATTRIBUTE */
3397     V_VT(&var) = VT_I1;
3398     V_I1(&var) = NODE_ATTRIBUTE;
3399     node = (IXMLDOMNode*)0x1;
3400     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3401     ok( r == E_FAIL, "returns %08x\n", r );
3402     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3403
3404     V_VT(&var) = VT_I1;
3405     V_I1(&var) = NODE_ATTRIBUTE;
3406     node = (IXMLDOMNode*)0x1;
3407     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3408     ok( r == E_FAIL, "returns %08x\n", r );
3409     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3410
3411     V_VT(&var) = VT_I1;
3412     V_I1(&var) = NODE_ATTRIBUTE;
3413     str = SysAllocString( szlc );
3414     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3415     ok( r == S_OK, "returns %08x\n", r );
3416     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3417     SysFreeString(str);
3418
3419     /* a name is required for attribute, try a BSTR with first null wchar */
3420     V_VT(&var) = VT_I1;
3421     V_I1(&var) = NODE_ATTRIBUTE;
3422     str = SysAllocString( szstr1 );
3423     str[0] = 0;
3424     node = (IXMLDOMNode*)0x1;
3425     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3426     ok( r == E_FAIL, "returns %08x\n", r );
3427     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3428     SysFreeString(str);
3429
3430     /* NODE_PROCESSING_INSTRUCTION */
3431     V_VT(&var) = VT_I1;
3432     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3433     node = (IXMLDOMNode*)0x1;
3434     r = IXMLDOMDocument_createNode( doc, var, NULL, 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_PROCESSING_INSTRUCTION;
3440     node = (IXMLDOMNode*)0x1;
3441     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3442     ok( r == E_FAIL, "returns %08x\n", r );
3443     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3444
3445     V_VT(&var) = VT_I1;
3446     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3447     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3448     ok( r == E_INVALIDARG, "returns %08x\n", r );
3449
3450     /* NODE_ENTITY_REFERENCE */
3451     V_VT(&var) = VT_I1;
3452     V_I1(&var) = NODE_ENTITY_REFERENCE;
3453     node = (IXMLDOMNode*)0x1;
3454     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3455     ok( r == E_FAIL, "returns %08x\n", r );
3456     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3457
3458     V_VT(&var) = VT_I1;
3459     V_I1(&var) = NODE_ENTITY_REFERENCE;
3460     node = (IXMLDOMNode*)0x1;
3461     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), 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     /* NODE_ELEMENT */
3466     V_VT(&var) = VT_I1;
3467     V_I1(&var) = NODE_ELEMENT;
3468     node = (IXMLDOMNode*)0x1;
3469     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3470     ok( r == E_FAIL, "returns %08x\n", r );
3471     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3472
3473     V_VT(&var) = VT_I1;
3474     V_I1(&var) = NODE_ELEMENT;
3475     node = (IXMLDOMNode*)0x1;
3476     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3477     ok( r == E_FAIL, "returns %08x\n", r );
3478     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3479
3480     V_VT(&var) = VT_I1;
3481     V_I1(&var) = NODE_ELEMENT;
3482     str = SysAllocString( szlc );
3483     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3484     ok( r == S_OK, "returns %08x\n", r );
3485     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3486
3487     V_VT(&var) = VT_I1;
3488     V_I1(&var) = NODE_ELEMENT;
3489     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3490     ok( r == E_INVALIDARG, "returns %08x\n", r );
3491
3492     V_VT(&var) = VT_R4;
3493     V_R4(&var) = NODE_ELEMENT;
3494     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3495     ok( r == S_OK, "returns %08x\n", r );
3496     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3497
3498     V_VT(&var) = VT_BSTR;
3499     V_BSTR(&var) = SysAllocString( szOne );
3500     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3501     ok( r == S_OK, "returns %08x\n", r );
3502     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3503     VariantClear(&var);
3504
3505     V_VT(&var) = VT_BSTR;
3506     V_BSTR(&var) = SysAllocString( szOneGarbage );
3507     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3508     ok( r == E_INVALIDARG, "returns %08x\n", r );
3509     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3510     VariantClear(&var);
3511
3512     V_VT(&var) = VT_I4;
3513     V_I4(&var) = NODE_ELEMENT;
3514     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3515     ok( r == S_OK, "returns %08x\n", r );
3516
3517     EXPECT_REF(doc, 1);
3518     r = IXMLDOMDocument_appendChild( doc, node, &root );
3519     ok( r == S_OK, "returns %08x\n", r );
3520     ok( node == root, "%p %p\n", node, root );
3521     EXPECT_REF(doc, 1);
3522
3523     EXPECT_REF(node, 2);
3524
3525     ref = IXMLDOMNode_Release( node );
3526     ok(ref == 1, "ref %d\n", ref);
3527     SysFreeString( str );
3528
3529     V_VT(&var) = VT_I4;
3530     V_I4(&var) = NODE_ELEMENT;
3531     str = SysAllocString( szbs );
3532     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3533     ok( r == S_OK, "returns %08x\n", r );
3534     SysFreeString( str );
3535
3536     EXPECT_REF(node, 1);
3537
3538     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3539     ok( r == S_OK, "returns %08x\n", r );
3540
3541     EXPECT_REF(unk, 2);
3542
3543     V_VT(&var) = VT_EMPTY;
3544     child = NULL;
3545     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3546     ok( r == S_OK, "returns %08x\n", r );
3547     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3548
3549     todo_wine EXPECT_REF(unk, 4);
3550
3551     IXMLDOMNode_Release( child );
3552     IUnknown_Release( unk );
3553
3554     V_VT(&var) = VT_NULL;
3555     V_DISPATCH(&var) = (IDispatch*)node;
3556     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3557     ok( r == S_OK, "returns %08x\n", r );
3558     ok( node == child, "%p %p\n", node, child );
3559     IXMLDOMNode_Release( child );
3560
3561     V_VT(&var) = VT_NULL;
3562     V_DISPATCH(&var) = (IDispatch*)node;
3563     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3564     ok( r == S_OK, "returns %08x\n", r );
3565     IXMLDOMNode_Release( node );
3566
3567     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3568     ok( r == S_OK, "returns %08x\n", r );
3569
3570     r = IXMLDOMElement_get_attributes( element, &attr_map );
3571     ok( r == S_OK, "returns %08x\n", r );
3572     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3573     ok( r == S_OK, "returns %08x\n", r );
3574     ok( num == 0, "num %d\n", num );
3575     IXMLDOMNamedNodeMap_Release( attr_map );
3576
3577     V_VT(&var) = VT_BSTR;
3578     V_BSTR(&var) = SysAllocString( szstr1 );
3579     name = SysAllocString( szdl );
3580     r = IXMLDOMElement_setAttribute( element, name, var );
3581     ok( r == S_OK, "returns %08x\n", r );
3582     r = IXMLDOMElement_get_attributes( element, &attr_map );
3583     ok( r == S_OK, "returns %08x\n", r );
3584     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3585     ok( r == S_OK, "returns %08x\n", r );
3586     ok( num == 1, "num %d\n", num );
3587     IXMLDOMNamedNodeMap_Release( attr_map );
3588     VariantClear(&var);
3589
3590     V_VT(&var) = VT_BSTR;
3591     V_BSTR(&var) = SysAllocString( szstr2 );
3592     r = IXMLDOMElement_setAttribute( element, name, var );
3593     ok( r == S_OK, "returns %08x\n", r );
3594     r = IXMLDOMElement_get_attributes( element, &attr_map );
3595     ok( r == S_OK, "returns %08x\n", r );
3596     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3597     ok( r == S_OK, "returns %08x\n", r );
3598     ok( num == 1, "num %d\n", num );
3599     IXMLDOMNamedNodeMap_Release( attr_map );
3600     VariantClear(&var);
3601     r = IXMLDOMElement_getAttribute( element, name, &var );
3602     ok( r == S_OK, "returns %08x\n", r );
3603     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3604     VariantClear(&var);
3605     SysFreeString(name);
3606
3607     V_VT(&var) = VT_BSTR;
3608     V_BSTR(&var) = SysAllocString( szstr1 );
3609     name = SysAllocString( szlc );
3610     r = IXMLDOMElement_setAttribute( element, name, var );
3611     ok( r == S_OK, "returns %08x\n", r );
3612     r = IXMLDOMElement_get_attributes( element, &attr_map );
3613     ok( r == S_OK, "returns %08x\n", r );
3614     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3615     ok( r == S_OK, "returns %08x\n", r );
3616     ok( num == 2, "num %d\n", num );
3617     IXMLDOMNamedNodeMap_Release( attr_map );
3618     VariantClear(&var);
3619     SysFreeString(name);
3620
3621     V_VT(&var) = VT_I4;
3622     V_I4(&var) = 10;
3623     name = SysAllocString( szbs );
3624     r = IXMLDOMElement_setAttribute( element, name, var );
3625     ok( r == S_OK, "returns %08x\n", r );
3626     VariantClear(&var);
3627     r = IXMLDOMElement_getAttribute( element, name, &var );
3628     ok( r == S_OK, "returns %08x\n", r );
3629     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3630     VariantClear(&var);
3631     SysFreeString(name);
3632
3633     /* Create an Attribute */
3634     V_VT(&var) = VT_I4;
3635     V_I4(&var) = NODE_ATTRIBUTE;
3636     str = SysAllocString( szAttribute );
3637     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3638     ok( r == S_OK, "returns %08x\n", r );
3639     ok( node != NULL, "node was null\n");
3640     SysFreeString(str);
3641
3642     IXMLDOMElement_Release( element );
3643     IXMLDOMNode_Release( root );
3644     IXMLDOMDocument_Release( doc );
3645 }
3646
3647 static void test_getElementsByTagName(void)
3648 {
3649     IXMLDOMNodeList *node_list;
3650     IXMLDOMDocument *doc;
3651     IXMLDOMElement *elem;
3652     WCHAR buff[100];
3653     VARIANT_BOOL b;
3654     HRESULT r;
3655     LONG len;
3656     BSTR str;
3657
3658     doc = create_document(&IID_IXMLDOMDocument);
3659     if (!doc) return;
3660
3661     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3662     ok( r == S_OK, "loadXML failed\n");
3663     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3664
3665     str = SysAllocString( szstar );
3666
3667     /* null arguments cases */
3668     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3669     ok( r == E_INVALIDARG, "ret %08x\n", r );
3670     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3671     ok( r == E_INVALIDARG, "ret %08x\n", r );
3672
3673     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3674     ok( r == S_OK, "ret %08x\n", r );
3675     r = IXMLDOMNodeList_get_length( node_list, &len );
3676     ok( r == S_OK, "ret %08x\n", r );
3677     ok( len == 6, "len %d\n", len );
3678
3679     IXMLDOMNodeList_Release( node_list );
3680     SysFreeString( str );
3681
3682     /* broken query BSTR */
3683     memcpy(&buff[2], szstar, sizeof(szstar));
3684     /* just a big length */
3685     *(DWORD*)buff = 0xf0f0;
3686     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3687     ok( r == S_OK, "ret %08x\n", r );
3688     r = IXMLDOMNodeList_get_length( node_list, &len );
3689     ok( r == S_OK, "ret %08x\n", r );
3690     ok( len == 6, "len %d\n", len );
3691     IXMLDOMNodeList_Release( node_list );
3692
3693     str = SysAllocString( szbs );
3694     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3695     ok( r == S_OK, "ret %08x\n", r );
3696     r = IXMLDOMNodeList_get_length( node_list, &len );
3697     ok( r == S_OK, "ret %08x\n", r );
3698     ok( len == 1, "len %d\n", len );
3699     IXMLDOMNodeList_Release( node_list );
3700     SysFreeString( str );
3701
3702     str = SysAllocString( szdl );
3703     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3704     ok( r == S_OK, "ret %08x\n", r );
3705     r = IXMLDOMNodeList_get_length( node_list, &len );
3706     ok( r == S_OK, "ret %08x\n", r );
3707     ok( len == 0, "len %d\n", len );
3708     IXMLDOMNodeList_Release( node_list );
3709     SysFreeString( str );
3710
3711     str = SysAllocString( szstr1 );
3712     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3713     ok( r == S_OK, "ret %08x\n", r );
3714     r = IXMLDOMNodeList_get_length( node_list, &len );
3715     ok( r == S_OK, "ret %08x\n", r );
3716     ok( len == 0, "len %d\n", len );
3717     IXMLDOMNodeList_Release( node_list );
3718     SysFreeString( str );
3719
3720     /* test for element */
3721     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3722     ok( r == S_OK, "ret %08x\n", r );
3723
3724     str = SysAllocString( szstar );
3725
3726     /* null arguments cases */
3727     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3728     ok( r == E_INVALIDARG, "ret %08x\n", r );
3729     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3730     ok( r == E_INVALIDARG, "ret %08x\n", r );
3731
3732     r = IXMLDOMElement_getElementsByTagName(elem, 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 == 5, "len %d\n", len );
3737     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3738     SysFreeString( str );
3739
3740     /* broken query BSTR */
3741     memcpy(&buff[2], szstar, sizeof(szstar));
3742     /* just a big length */
3743     *(DWORD*)buff = 0xf0f0;
3744     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3745     ok( r == S_OK, "ret %08x\n", r );
3746     r = IXMLDOMNodeList_get_length( node_list, &len );
3747     ok( r == S_OK, "ret %08x\n", r );
3748     ok( len == 5, "len %d\n", len );
3749     IXMLDOMNodeList_Release( node_list );
3750
3751     IXMLDOMElement_Release(elem);
3752
3753     IXMLDOMDocument_Release( doc );
3754
3755     free_bstrs();
3756 }
3757
3758 static void test_get_text(void)
3759 {
3760     HRESULT r;
3761     BSTR str;
3762     VARIANT_BOOL b;
3763     IXMLDOMDocument *doc;
3764     IXMLDOMNode *node, *node2, *node3;
3765     IXMLDOMNode *nodeRoot;
3766     IXMLDOMNodeList *node_list;
3767     IXMLDOMNamedNodeMap *node_map;
3768     LONG len;
3769
3770     doc = create_document(&IID_IXMLDOMDocument);
3771     if (!doc) return;
3772
3773     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3774     ok( r == S_OK, "loadXML failed\n");
3775     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3776
3777     str = SysAllocString( szbs );
3778     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3779     ok( r == S_OK, "ret %08x\n", r );
3780     SysFreeString(str);
3781
3782     /* Test to get all child node text. */
3783     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3784     ok( r == S_OK, "ret %08x\n", r );
3785     if(r == S_OK)
3786     {
3787         r = IXMLDOMNode_get_text( nodeRoot, &str );
3788         ok( r == S_OK, "ret %08x\n", r );
3789         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
3790         SysFreeString(str);
3791
3792         IXMLDOMNode_Release(nodeRoot);
3793     }
3794
3795     r = IXMLDOMNodeList_get_length( node_list, NULL );
3796     ok( r == E_INVALIDARG, "ret %08x\n", r );
3797
3798     r = IXMLDOMNodeList_get_length( node_list, &len );
3799     ok( r == S_OK, "ret %08x\n", r );
3800     ok( len == 1, "expect 1 got %d\n", len );
3801
3802     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3803     ok( r == E_INVALIDARG, "ret %08x\n", r );
3804
3805     r = IXMLDOMNodeList_nextNode( node_list, NULL );
3806     ok( r == E_INVALIDARG, "ret %08x\n", r );
3807
3808     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
3809     ok( r == S_OK, "ret %08x\n", r );
3810     IXMLDOMNodeList_Release( node_list );
3811
3812     /* Invalid output parameter*/
3813     r = IXMLDOMNode_get_text( node, NULL );
3814     ok( r == E_INVALIDARG, "ret %08x\n", r );
3815
3816     r = IXMLDOMNode_get_text( node, &str );
3817     ok( r == S_OK, "ret %08x\n", r );
3818     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
3819     SysFreeString(str);
3820
3821     r = IXMLDOMNode_get_attributes( node, &node_map );
3822     ok( r == S_OK, "ret %08x\n", r );
3823
3824     str = SysAllocString( szvr );
3825     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3826     ok( r == S_OK, "ret %08x\n", r );
3827     SysFreeString(str);
3828
3829     r = IXMLDOMNode_get_text( node2, &str );
3830     ok( r == S_OK, "ret %08x\n", r );
3831     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3832     SysFreeString(str);
3833
3834     r = IXMLDOMNode_get_firstChild( node2, &node3 );
3835     ok( r == S_OK, "ret %08x\n", r );
3836
3837     r = IXMLDOMNode_get_text( node3, &str );
3838     ok( r == S_OK, "ret %08x\n", r );
3839     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3840     SysFreeString(str);
3841
3842
3843     IXMLDOMNode_Release( node3 );
3844     IXMLDOMNode_Release( node2 );
3845     IXMLDOMNamedNodeMap_Release( node_map );
3846     IXMLDOMNode_Release( node );
3847     IXMLDOMDocument_Release( doc );
3848
3849     free_bstrs();
3850 }
3851
3852 static void test_get_childNodes(void)
3853 {
3854     BSTR str;
3855     VARIANT_BOOL b;
3856     IXMLDOMDocument *doc;
3857     IXMLDOMElement *element;
3858     IXMLDOMNode *node, *node2;
3859     IXMLDOMNodeList *node_list, *node_list2;
3860     HRESULT hr;
3861     LONG len;
3862
3863     doc = create_document(&IID_IXMLDOMDocument);
3864     if (!doc) return;
3865
3866     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3867     EXPECT_HR(hr, S_OK);
3868     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3869
3870     hr = IXMLDOMDocument_get_documentElement( doc, &element );
3871     EXPECT_HR(hr, S_OK);
3872
3873     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3874     EXPECT_HR(hr, S_OK);
3875
3876     hr = IXMLDOMNodeList_get_length( node_list, &len );
3877     EXPECT_HR(hr, S_OK);
3878     ok( len == 4, "len %d\n", len);
3879
3880     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3881     EXPECT_HR(hr, S_OK);
3882
3883     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3884     EXPECT_HR(hr, S_OK);
3885
3886     hr = IXMLDOMNodeList_get_length( node_list2, &len );
3887     EXPECT_HR(hr, S_OK);
3888     ok( len == 0, "len %d\n", len);
3889
3890     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3891     EXPECT_HR(hr, S_FALSE);
3892
3893     IXMLDOMNodeList_Release( node_list2 );
3894     IXMLDOMNode_Release( node );
3895     IXMLDOMNodeList_Release( node_list );
3896     IXMLDOMElement_Release( element );
3897
3898     /* test for children of <?xml ..?> node */
3899     hr = IXMLDOMDocument_get_firstChild(doc, &node);
3900     EXPECT_HR(hr, S_OK);
3901
3902     str = NULL;
3903     hr = IXMLDOMNode_get_nodeName(node, &str);
3904     EXPECT_HR(hr, S_OK);
3905     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
3906     SysFreeString(str);
3907
3908     /* it returns empty but valid node list */
3909     node_list = (void*)0xdeadbeef;
3910     hr = IXMLDOMNode_get_childNodes(node, &node_list);
3911     EXPECT_HR(hr, S_OK);
3912
3913     len = -1;
3914     hr = IXMLDOMNodeList_get_length(node_list, &len);
3915     EXPECT_HR(hr, S_OK);
3916     ok(len == 0, "got %d\n", len);
3917
3918     IXMLDOMNodeList_Release( node_list );
3919     IXMLDOMNode_Release(node);
3920
3921     IXMLDOMDocument_Release( doc );
3922     free_bstrs();
3923 }
3924
3925 static void test_get_firstChild(void)
3926 {
3927     static WCHAR xmlW[] = {'x','m','l',0};
3928     IXMLDOMDocument *doc;
3929     IXMLDOMNode *node;
3930     VARIANT_BOOL b;
3931     HRESULT r;
3932     BSTR str;
3933
3934     doc = create_document(&IID_IXMLDOMDocument);
3935     if (!doc) return;
3936
3937     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3938     ok( r == S_OK, "loadXML failed\n");
3939     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3940
3941     r = IXMLDOMDocument_get_firstChild( doc, &node );
3942     ok( r == S_OK, "ret %08x\n", r);
3943
3944     r = IXMLDOMNode_get_nodeName( node, &str );
3945     ok( r == S_OK, "ret %08x\n", r);
3946
3947     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3948
3949     SysFreeString(str);
3950     IXMLDOMNode_Release( node );
3951     IXMLDOMDocument_Release( doc );
3952
3953     free_bstrs();
3954 }
3955
3956 static void test_get_lastChild(void)
3957 {
3958     static WCHAR lcW[] = {'l','c',0};
3959     static WCHAR foW[] = {'f','o',0};
3960     IXMLDOMDocument *doc;
3961     IXMLDOMNode *node, *child;
3962     VARIANT_BOOL b;
3963     HRESULT r;
3964     BSTR str;
3965
3966     doc = create_document(&IID_IXMLDOMDocument);
3967     if (!doc) return;
3968
3969     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3970     ok( r == S_OK, "loadXML failed\n");
3971     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3972
3973     r = IXMLDOMDocument_get_lastChild( doc, &node );
3974     ok( r == S_OK, "ret %08x\n", r);
3975
3976     r = IXMLDOMNode_get_nodeName( node, &str );
3977     ok( r == S_OK, "ret %08x\n", r);
3978
3979     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
3980     SysFreeString(str);
3981
3982     r = IXMLDOMNode_get_lastChild( node, &child );
3983     ok( r == S_OK, "ret %08x\n", r);
3984
3985     r = IXMLDOMNode_get_nodeName( child, &str );
3986     ok( r == S_OK, "ret %08x\n", r);
3987
3988     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
3989     SysFreeString(str);
3990
3991     IXMLDOMNode_Release( child );
3992     IXMLDOMNode_Release( node );
3993     IXMLDOMDocument_Release( doc );
3994
3995     free_bstrs();
3996 }
3997
3998 static void test_removeChild(void)
3999 {
4000     HRESULT r;
4001     VARIANT_BOOL b;
4002     IXMLDOMDocument *doc;
4003     IXMLDOMElement *element, *lc_element;
4004     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4005     IXMLDOMNodeList *root_list, *fo_list;
4006
4007     doc = create_document(&IID_IXMLDOMDocument);
4008     if (!doc) return;
4009
4010     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4011     ok( r == S_OK, "loadXML failed\n");
4012     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4013
4014     r = IXMLDOMDocument_get_documentElement( doc, &element );
4015     ok( r == S_OK, "ret %08x\n", r);
4016     todo_wine EXPECT_REF(element, 2);
4017
4018     r = IXMLDOMElement_get_childNodes( element, &root_list );
4019     ok( r == S_OK, "ret %08x\n", r);
4020     EXPECT_REF(root_list, 1);
4021
4022     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4023     ok( r == S_OK, "ret %08x\n", r);
4024     EXPECT_REF(fo_node, 1);
4025
4026     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4027     ok( r == S_OK, "ret %08x\n", r);
4028     EXPECT_REF(fo_list, 1);
4029
4030     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4031     ok( r == S_OK, "ret %08x\n", r);
4032     EXPECT_REF(ba_node, 1);
4033
4034     /* invalid parameter: NULL ptr */
4035     removed_node = (void*)0xdeadbeef;
4036     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4037     ok( r == E_INVALIDARG, "ret %08x\n", r );
4038     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4039
4040     /* ba_node is a descendant of element, but not a direct child. */
4041     removed_node = (void*)0xdeadbeef;
4042     EXPECT_REF(ba_node, 1);
4043     EXPECT_CHILDREN(fo_node);
4044     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4045     ok( r == E_INVALIDARG, "ret %08x\n", r );
4046     ok( removed_node == NULL, "%p\n", removed_node );
4047     EXPECT_REF(ba_node, 1);
4048     EXPECT_CHILDREN(fo_node);
4049
4050     EXPECT_REF(ba_node, 1);
4051     EXPECT_REF(fo_node, 1);
4052     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4053     ok( r == S_OK, "ret %08x\n", r);
4054     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4055     EXPECT_REF(fo_node, 2);
4056     EXPECT_REF(ba_node, 1);
4057
4058     /* try removing already removed child */
4059     temp_node = (void*)0xdeadbeef;
4060     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4061     ok( r == E_INVALIDARG, "ret %08x\n", r);
4062     ok( temp_node == NULL, "%p\n", temp_node );
4063     IXMLDOMNode_Release( fo_node );
4064
4065     /* the removed node has no parent anymore */
4066     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4067     ok( r == S_FALSE, "ret %08x\n", r);
4068     ok( temp_node == NULL, "%p\n", temp_node );
4069
4070     IXMLDOMNode_Release( removed_node );
4071     IXMLDOMNode_Release( ba_node );
4072     IXMLDOMNodeList_Release( fo_list );
4073
4074     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4075     ok( r == S_OK, "ret %08x\n", r);
4076
4077     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4078     ok( r == S_OK, "ret %08x\n", r);
4079
4080     /* MS quirk: passing wrong interface pointer works, too */
4081     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4082     ok( r == S_OK, "ret %08x\n", r);
4083     IXMLDOMElement_Release( lc_element );
4084
4085     temp_node = (void*)0xdeadbeef;
4086     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4087     ok( r == S_FALSE, "ret %08x\n", r);
4088     ok( temp_node == NULL, "%p\n", temp_node );
4089
4090     IXMLDOMNode_Release( lc_node );
4091     IXMLDOMNodeList_Release( root_list );
4092     IXMLDOMElement_Release( element );
4093     IXMLDOMDocument_Release( doc );
4094
4095     free_bstrs();
4096 }
4097
4098 static void test_replaceChild(void)
4099 {
4100     HRESULT r;
4101     VARIANT_BOOL b;
4102     IXMLDOMDocument *doc;
4103     IXMLDOMElement *element, *ba_element;
4104     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4105     IXMLDOMNodeList *root_list, *fo_list;
4106     IUnknown * unk1, *unk2;
4107     LONG len;
4108
4109     doc = create_document(&IID_IXMLDOMDocument);
4110     if (!doc) return;
4111
4112     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4113     ok( r == S_OK, "loadXML failed\n");
4114     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4115
4116     r = IXMLDOMDocument_get_documentElement( doc, &element );
4117     ok( r == S_OK, "ret %08x\n", r);
4118
4119     r = IXMLDOMElement_get_childNodes( element, &root_list );
4120     ok( r == S_OK, "ret %08x\n", r);
4121
4122     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4123     ok( r == S_OK, "ret %08x\n", r);
4124
4125     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4126     ok( r == S_OK, "ret %08x\n", r);
4127
4128     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4129     ok( r == S_OK, "ret %08x\n", r);
4130
4131     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4132     ok( r == S_OK, "ret %08x\n", r);
4133
4134     IXMLDOMNodeList_Release( fo_list );
4135
4136     /* invalid parameter: NULL ptr for element to remove */
4137     removed_node = (void*)0xdeadbeef;
4138     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4139     ok( r == E_INVALIDARG, "ret %08x\n", r );
4140     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4141
4142     /* invalid parameter: NULL for replacement element. (Sic!) */
4143     removed_node = (void*)0xdeadbeef;
4144     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4145     ok( r == E_INVALIDARG, "ret %08x\n", r );
4146     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4147
4148     /* invalid parameter: OldNode is not a child */
4149     removed_node = (void*)0xdeadbeef;
4150     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4151     ok( r == E_INVALIDARG, "ret %08x\n", r );
4152     ok( removed_node == NULL, "%p\n", removed_node );
4153     IXMLDOMNode_Release( lc_node );
4154
4155     /* invalid parameter: would create loop */
4156     removed_node = (void*)0xdeadbeef;
4157     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4158     ok( r == E_FAIL, "ret %08x\n", r );
4159     ok( removed_node == NULL, "%p\n", removed_node );
4160
4161     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4162     ok( r == S_OK, "ret %08x\n", r );
4163
4164     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4165     ok( r == S_OK, "ret %08x\n", r );
4166
4167     /* ba_node and temp_node refer to the same node, yet they
4168        are different interface pointers */
4169     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4170     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4171     ok( r == S_OK, "ret %08x\n", r );
4172     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4173     ok( r == S_OK, "ret %08x\n", r );
4174     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4175
4176     IUnknown_Release( unk1 );
4177     IUnknown_Release( unk2 );
4178
4179     /* ba_node should have been removed from below fo_node */
4180     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4181     ok( r == S_OK, "ret %08x\n", r );
4182
4183     /* MS quirk: replaceChild also accepts elements instead of nodes */
4184     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4185     ok( r == S_OK, "ret %08x\n", r );
4186     EXPECT_REF(ba_element, 2);
4187
4188     removed_node = NULL;
4189     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4190     ok( r == S_OK, "ret %08x\n", r );
4191     ok( removed_node != NULL, "got %p\n", removed_node);
4192     EXPECT_REF(ba_element, 3);
4193     IXMLDOMElement_Release( ba_element );
4194
4195     r = IXMLDOMNodeList_get_length( fo_list, &len);
4196     ok( r == S_OK, "ret %08x\n", r );
4197     ok( len == 0, "len %d\n", len);
4198
4199     IXMLDOMNodeList_Release( fo_list );
4200
4201     IXMLDOMNode_Release(ba_node);
4202     IXMLDOMNode_Release(fo_node);
4203     IXMLDOMNode_Release(temp_node);
4204     IXMLDOMNodeList_Release( root_list );
4205     IXMLDOMElement_Release( element );
4206     IXMLDOMDocument_Release( doc );
4207
4208     free_bstrs();
4209 }
4210
4211 static void test_removeNamedItem(void)
4212 {
4213     IXMLDOMDocument *doc;
4214     IXMLDOMElement *element;
4215     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4216     IXMLDOMNodeList *root_list;
4217     IXMLDOMNamedNodeMap * pr_attrs;
4218     VARIANT_BOOL b;
4219     BSTR str;
4220     LONG len;
4221     HRESULT r;
4222
4223     doc = create_document(&IID_IXMLDOMDocument);
4224     if (!doc) return;
4225
4226     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4227     ok( r == S_OK, "loadXML failed\n");
4228     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4229
4230     r = IXMLDOMDocument_get_documentElement( doc, &element );
4231     ok( r == S_OK, "ret %08x\n", r);
4232
4233     r = IXMLDOMElement_get_childNodes( element, &root_list );
4234     ok( r == S_OK, "ret %08x\n", r);
4235
4236     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4237     ok( r == S_OK, "ret %08x\n", r);
4238
4239     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4240     ok( r == S_OK, "ret %08x\n", r);
4241
4242     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4243     ok( r == S_OK, "ret %08x\n", r);
4244     ok( len == 3, "length %d\n", len);
4245
4246     removed_node = (void*)0xdeadbeef;
4247     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4248     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4249     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4250
4251     removed_node = (void*)0xdeadbeef;
4252     str = SysAllocString(szvr);
4253     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4254     ok ( r == S_OK, "ret %08x\n", r);
4255
4256     removed_node2 = (void*)0xdeadbeef;
4257     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4258     ok ( r == S_FALSE, "ret %08x\n", r);
4259     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4260
4261     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4262     ok( r == S_OK, "ret %08x\n", r);
4263     ok( len == 2, "length %d\n", len);
4264
4265     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4266     ok ( r == S_OK, "ret %08x\n", r);
4267     IXMLDOMNode_Release(removed_node);
4268
4269     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4270     ok( r == S_OK, "ret %08x\n", r);
4271     ok( len == 3, "length %d\n", len);
4272
4273     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4274     ok ( r == S_OK, "ret %08x\n", r);
4275
4276     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4277     ok( r == S_OK, "ret %08x\n", r);
4278     ok( len == 2, "length %d\n", len);
4279
4280     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4281     ok ( r == S_FALSE, "ret %08x\n", r);
4282
4283     SysFreeString(str);
4284
4285     IXMLDOMNamedNodeMap_Release( pr_attrs );
4286     IXMLDOMNode_Release( pr_node );
4287     IXMLDOMNodeList_Release( root_list );
4288     IXMLDOMElement_Release( element );
4289     IXMLDOMDocument_Release( doc );
4290
4291     free_bstrs();
4292 }
4293
4294 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4295 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4296                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4297                                     DWORD expected2)
4298 {
4299     DWORD enabled, supported;
4300     HRESULT hr;
4301
4302     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4303     if (result == result2)
4304         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4305     else
4306         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4307            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4308
4309     supported = enabled = 0xCAFECAFE;
4310     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4311     ok(hr == S_OK, "ret %08x\n", hr );
4312     if (expected == expected2)
4313         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4314     else
4315         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4316            "Expected %08x, got %08x\n", expected2, enabled);
4317
4318     /* reset the safety options */
4319
4320     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4321             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4322             0);
4323     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4324
4325     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4326     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4327     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4328 }
4329
4330 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4331 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4332 {
4333     DWORD enabled = 0, supported = 0;
4334     HRESULT hr;
4335
4336     /* get */
4337     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4338     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4339     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4340     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4341
4342     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4343     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4344     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4345        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4346         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4347              "got %08x\n", supported);
4348     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4349
4350     /* set -- individual flags */
4351
4352     test_IObjectSafety_set(safety, S_OK, S_OK,
4353         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4354         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4355
4356     test_IObjectSafety_set(safety, S_OK, S_OK,
4357         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4358         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4359
4360     test_IObjectSafety_set(safety, S_OK, S_OK,
4361         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4362         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4363
4364     /* set INTERFACE_USES_DISPEX  */
4365
4366     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4367         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4368         0, 0);
4369
4370     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4371         INTERFACE_USES_DISPEX, 0,
4372         0, 0);
4373
4374     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4375         0, INTERFACE_USES_DISPEX,
4376         0, 0);
4377
4378     /* set option masking */
4379
4380     test_IObjectSafety_set(safety, S_OK, S_OK,
4381         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4382         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4383         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4384         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4385
4386     test_IObjectSafety_set(safety, S_OK, S_OK,
4387         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4388         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4389         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4390         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4391
4392     test_IObjectSafety_set(safety, S_OK, S_OK,
4393         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4394         INTERFACE_USES_SECURITY_MANAGER,
4395         0,
4396         0);
4397
4398     /* set -- inheriting previous settings */
4399
4400     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4401                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4402                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4403     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4404     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4405     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4406     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4407     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4408        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4409         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4410              "got %08x\n", supported);
4411
4412     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4413                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4414                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4415     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4416     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4417     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4418     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4419                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4420                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4421     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4422        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4423         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4424              "got %08x\n", supported);
4425 }
4426
4427 static void test_XMLHTTP(void)
4428 {
4429     static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
4430     static const WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
4431         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4432         'p','o','s','t','t','e','s','t','.','p','h','p',0};
4433     static const WCHAR xmltestW[] = {'h','t','t','p',':','/','/',
4434         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4435         'x','m','l','t','e','s','t','.','x','m','l',0};
4436     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4437     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4438
4439     IXMLHttpRequest *xhr;
4440     IObjectSafety *safety;
4441     IObjectWithSite *obj_site, *obj_site2;
4442     BSTR bstrResponse, url;
4443     VARIANT dummy;
4444     VARIANT async;
4445     VARIANT varbody;
4446     LONG state, status, bound;
4447     IDispatch *event;
4448     void *ptr;
4449     HRESULT hr;
4450
4451     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4452         &IID_IXMLHttpRequest, (void**)&xhr);
4453     if (FAILED(hr))
4454     {
4455         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4456         return;
4457     }
4458
4459     VariantInit(&dummy);
4460     V_VT(&dummy) = VT_ERROR;
4461     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4462     VariantInit(&async);
4463     V_VT(&async) = VT_BOOL;
4464     V_BOOL(&async) = VARIANT_FALSE;
4465     V_VT(&varbody) = VT_BSTR;
4466     V_BSTR(&varbody) = SysAllocString(wszBody);
4467
4468     url = SysAllocString(wszUrl);
4469
4470     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4471     EXPECT_HR(hr, S_OK);
4472
4473     hr = IXMLHttpRequest_abort(xhr);
4474     EXPECT_HR(hr, S_OK);
4475
4476     /* send before open */
4477     hr = IXMLHttpRequest_send(xhr, dummy);
4478     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4479
4480     /* initial status code */
4481     hr = IXMLHttpRequest_get_status(xhr, NULL);
4482     EXPECT_HR(hr, E_INVALIDARG);
4483
4484     status = 0xdeadbeef;
4485     hr = IXMLHttpRequest_get_status(xhr, &status);
4486     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4487     ok(status == 0xdeadbeef, "got %d\n", status);
4488
4489     /* invalid parameters */
4490     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4491     EXPECT_HR(hr, E_INVALIDARG);
4492
4493     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4494     EXPECT_HR(hr, E_INVALIDARG);
4495
4496     hr = IXMLHttpRequest_open(xhr, NULL, url, async, dummy, dummy);
4497     EXPECT_HR(hr, E_INVALIDARG);
4498
4499     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4500     EXPECT_HR(hr, E_INVALIDARG);
4501
4502     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4503     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4504
4505     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4506     EXPECT_HR(hr, E_INVALIDARG);
4507
4508     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4509     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4510
4511     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4512     EXPECT_HR(hr, E_INVALIDARG);
4513
4514     state = -1;
4515     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4516     EXPECT_HR(hr, S_OK);
4517     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4518
4519     event = create_dispevent();
4520
4521     EXPECT_REF(event, 1);
4522     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4523     EXPECT_HR(hr, S_OK);
4524     EXPECT_REF(event, 2);
4525
4526     g_unexpectedcall = g_expectedcall = 0;
4527
4528     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4529     EXPECT_HR(hr, S_OK);
4530
4531     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4532     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4533
4534     /* status code after ::open() */
4535     status = 0xdeadbeef;
4536     hr = IXMLHttpRequest_get_status(xhr, &status);
4537     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4538     ok(status == 0xdeadbeef, "got %d\n", status);
4539
4540     state = -1;
4541     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4542     EXPECT_HR(hr, S_OK);
4543     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4544
4545     hr = IXMLHttpRequest_abort(xhr);
4546     EXPECT_HR(hr, S_OK);
4547
4548     state = -1;
4549     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4550     EXPECT_HR(hr, S_OK);
4551     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4552         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4553
4554     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4555     EXPECT_HR(hr, S_OK);
4556
4557     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4558     EXPECT_HR(hr, S_OK);
4559
4560     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4561     EXPECT_HR(hr, E_INVALIDARG);
4562
4563     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4564     EXPECT_HR(hr, E_INVALIDARG);
4565
4566     SysFreeString(url);
4567
4568     hr = IXMLHttpRequest_send(xhr, varbody);
4569     if (hr == INET_E_RESOURCE_NOT_FOUND)
4570     {
4571         skip("No connection could be made with crossover.codeweavers.com\n");
4572         IXMLHttpRequest_Release(xhr);
4573         return;
4574     }
4575     EXPECT_HR(hr, S_OK);
4576
4577     /* status code after ::send() */
4578     status = 0xdeadbeef;
4579     hr = IXMLHttpRequest_get_status(xhr, &status);
4580     EXPECT_HR(hr, S_OK);
4581     ok(status == 200, "got %d\n", status);
4582
4583     /* another ::send() after completed request */
4584     hr = IXMLHttpRequest_send(xhr, varbody);
4585     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4586
4587     VariantClear(&varbody);
4588
4589     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4590     EXPECT_HR(hr, S_OK);
4591     /* the server currently returns "FAILED" because the Content-Type header is
4592      * not what the server expects */
4593     if(hr == S_OK)
4594     {
4595         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4596             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4597         SysFreeString(bstrResponse);
4598     }
4599
4600     /* GET request */
4601     url = SysAllocString(xmltestW);
4602
4603     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), url, async, dummy, dummy);
4604     EXPECT_HR(hr, S_OK);
4605
4606     V_VT(&varbody) = VT_EMPTY;
4607
4608     hr = IXMLHttpRequest_send(xhr, varbody);
4609     if (hr == INET_E_RESOURCE_NOT_FOUND)
4610     {
4611         skip("No connection could be made with crossover.codeweavers.com\n");
4612         IXMLHttpRequest_Release(xhr);
4613         return;
4614     }
4615     EXPECT_HR(hr, S_OK);
4616
4617     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4618     EXPECT_HR(hr, E_INVALIDARG);
4619
4620     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4621     EXPECT_HR(hr, S_OK);
4622     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4623         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4624     SysFreeString(bstrResponse);
4625
4626     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4627     EXPECT_HR(hr, E_INVALIDARG);
4628
4629     V_VT(&varbody) = VT_EMPTY;
4630     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4631     EXPECT_HR(hr, S_OK);
4632     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4633     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4634
4635     bound = -1;
4636     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4637     EXPECT_HR(hr, S_OK);
4638     ok(bound == 0, "got %d, expected zero bound\n", bound);
4639
4640     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4641     EXPECT_HR(hr, S_OK);
4642     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4643     SafeArrayUnaccessData(V_ARRAY(&varbody));
4644
4645     VariantClear(&varbody);
4646
4647     SysFreeString(url);
4648
4649     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4650     EXPECT_HR(hr, S_OK);
4651     if(hr == S_OK)
4652     {
4653         test_IObjectSafety_common(safety);
4654         IObjectSafety_Release(safety);
4655     }
4656
4657     IDispatch_Release(event);
4658
4659     /* interaction with object site */
4660     EXPECT_REF(xhr, 1);
4661     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4662     EXPECT_HR(hr, S_OK);
4663 todo_wine {
4664     EXPECT_REF(xhr, 1);
4665     EXPECT_REF(obj_site, 1);
4666 }
4667
4668     IObjectWithSite_AddRef(obj_site);
4669 todo_wine {
4670     EXPECT_REF(obj_site, 2);
4671     EXPECT_REF(xhr, 1);
4672 }
4673     IObjectWithSite_Release(obj_site);
4674
4675     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
4676     EXPECT_HR(hr, S_OK);
4677 todo_wine {
4678     EXPECT_REF(xhr, 1);
4679     EXPECT_REF(obj_site, 1);
4680     EXPECT_REF(obj_site2, 1);
4681     ok(obj_site != obj_site2, "expected new instance\n");
4682 }
4683     SET_EXPECT(site_qi_IServiceProvider);
4684     SET_EXPECT(sp_queryservice_SID_SBindHost);
4685     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4686     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
4687     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
4688     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
4689
4690     /* calls to IHTMLDocument2 */
4691     SET_EXPECT(htmldoc2_get_all);
4692     SET_EXPECT(collection_get_length);
4693     SET_EXPECT(htmldoc2_get_url);
4694
4695     SET_EXPECT(site_qi_IXMLDOMDocument);
4696     SET_EXPECT(site_qi_IOleClientSite);
4697
4698     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
4699     EXPECT_HR(hr, S_OK);
4700
4701 todo_wine{
4702     CHECK_CALLED(site_qi_IServiceProvider);
4703
4704     CHECK_CALLED(sp_queryservice_SID_SBindHost);
4705     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4706     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
4707     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
4708     /* this one isn't very reliable
4709     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
4710
4711     CHECK_CALLED(htmldoc2_get_all);
4712     CHECK_CALLED(collection_get_length);
4713     CHECK_CALLED(htmldoc2_get_url);
4714
4715     CHECK_CALLED(site_qi_IXMLDOMDocument);
4716     CHECK_CALLED(site_qi_IOleClientSite);
4717 }
4718     IObjectWithSite_Release(obj_site);
4719
4720     todo_wine EXPECT_REF(xhr, 1);
4721     IXMLHttpRequest_Release(xhr);
4722
4723     /* still works after request is released */
4724     SET_EXPECT(site_qi_IServiceProvider);
4725
4726     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
4727     EXPECT_HR(hr, S_OK);
4728     IObjectWithSite_Release(obj_site2);
4729
4730     free_bstrs();
4731 }
4732
4733 static void test_IXMLDOMDocument2(void)
4734 {
4735     static const WCHAR emptyW[] = {0};
4736     IXMLDOMDocument2 *doc2, *dtddoc2;
4737     IXMLDOMDocument *doc;
4738     IXMLDOMParseError* err;
4739     IDispatchEx *dispex;
4740     VARIANT_BOOL b;
4741     VARIANT var;
4742     HRESULT r;
4743     LONG res;
4744
4745     doc = create_document(&IID_IXMLDOMDocument);
4746     if (!doc) return;
4747
4748     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4749     if (!dtddoc2)
4750     {
4751         IXMLDOMDocument_Release(doc);
4752         return;
4753     }
4754
4755     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4756     ok( r == S_OK, "ret %08x\n", r );
4757     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4758
4759     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4760     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4761     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4762
4763     err = NULL;
4764     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4765     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4766     ok(err != NULL, "expected a pointer\n");
4767     if (err)
4768     {
4769         res = 0;
4770         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4771         /* XML_E_NOTWF */
4772         ok(res == E_XML_NOTWF, "got %08x\n", res);
4773         IXMLDOMParseError_Release(err);
4774     }
4775
4776     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
4777     ok( r == S_OK, "loadXML failed\n");
4778     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4779
4780     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
4781     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4782
4783     err = NULL;
4784     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4785     ok(err != NULL, "expected a pointer\n");
4786     if (err)
4787     {
4788         res = 0;
4789         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4790         /* XML_E_NODTD */
4791         ok(res == E_XML_NODTD, "got %08x\n", res);
4792         IXMLDOMParseError_Release(err);
4793     }
4794
4795     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4796     ok( r == S_OK, "ret %08x\n", r );
4797     if(r == S_OK)
4798     {
4799         IDispatchEx_Release(dispex);
4800     }
4801
4802     /* we will check if the variant got cleared */
4803     IXMLDOMDocument2_AddRef(doc2);
4804     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4805
4806     V_VT(&var) = VT_UNKNOWN;
4807     V_UNKNOWN(&var) = (IUnknown *)doc2;
4808
4809     /* invalid calls */
4810     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
4811     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4812     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
4813
4814     /* valid call */
4815     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4816     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4817     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4818     V_VT(&var) = VT_R4;
4819
4820     /* the variant didn't get cleared*/
4821     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4822
4823     /* setProperty tests */
4824     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
4825     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
4826     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
4827     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4828     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4829     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4830
4831     V_VT(&var) = VT_BSTR;
4832     V_BSTR(&var) = SysAllocString(emptyW);
4833     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4834     ok(r == S_OK, "got 0x%08x\n", r);
4835     VariantClear(&var);
4836
4837     V_VT(&var) = VT_I2;
4838     V_I2(&var) = 0;
4839     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4840     ok(r == E_FAIL, "got 0x%08x\n", r);
4841
4842     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4843     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4844     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4845     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4846
4847     IXMLDOMDocument2_Release( doc2 );
4848     IXMLDOMDocument_Release( doc );
4849
4850     /* DTD validation */
4851     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
4852     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
4853     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4854     err = NULL;
4855     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
4856     ok(err != NULL, "expected pointer\n");
4857     if (err)
4858     {
4859         res = 0;
4860         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
4861         ok(res == 0, "got %08x\n", res);
4862         IXMLDOMParseError_Release(err);
4863     }
4864
4865     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
4866     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4867     err = NULL;
4868     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4869     ok(err != NULL, "expected pointer\n");
4870     if (err)
4871     {
4872         res = 0;
4873         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4874         /* XML_ELEMENT_UNDECLARED */
4875         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
4876         IXMLDOMParseError_Release(err);
4877     }
4878
4879     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
4880     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4881     err = NULL;
4882     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4883     ok(err != NULL, "expected pointer\n");
4884     if (err)
4885     {
4886         res = 0;
4887         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4888         /* XML_ELEMENT_ID_NOT_FOUND */
4889         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
4890         IXMLDOMParseError_Release(err);
4891     }
4892
4893     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
4894     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4895     err = NULL;
4896     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4897     ok(err != NULL, "expected pointer\n");
4898     if (err)
4899     {
4900         res = 0;
4901         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4902         /* XML_EMPTY_NOT_ALLOWED */
4903         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
4904         IXMLDOMParseError_Release(err);
4905     }
4906
4907     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
4908     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4909     err = NULL;
4910     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4911     ok(err != NULL, "expected pointer\n");
4912     if (err)
4913     {
4914         res = 0;
4915         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4916         /* XML_ROOT_NAME_MISMATCH */
4917         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
4918         IXMLDOMParseError_Release(err);
4919     }
4920
4921     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
4922     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4923     err = NULL;
4924     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4925     ok(err != NULL, "expected pointer\n");
4926     if (err)
4927     {
4928         res = 0;
4929         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4930         /* XML_INVALID_CONTENT */
4931         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
4932         IXMLDOMParseError_Release(err);
4933     }
4934
4935     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
4936     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4937     err = NULL;
4938     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4939     ok(err != NULL, "expected pointer\n");
4940     if (err)
4941     {
4942         res = 0;
4943         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4944         /* XML_ATTRIBUTE_NOT_DEFINED */
4945         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
4946         IXMLDOMParseError_Release(err);
4947     }
4948
4949     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
4950     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4951     err = NULL;
4952     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4953     ok(err != NULL, "expected pointer\n");
4954     if (err)
4955     {
4956         res = 0;
4957         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4958         /* XML_ATTRIBUTE_FIXED */
4959         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
4960         IXMLDOMParseError_Release(err);
4961     }
4962
4963     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
4964     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4965     err = NULL;
4966     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4967     ok(err != NULL, "expected pointer\n");
4968     if (err)
4969     {
4970         res = 0;
4971         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4972         /* XML_ATTRIBUTE_VALUE */
4973         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
4974         IXMLDOMParseError_Release(err);
4975     }
4976
4977     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
4978     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4979     err = NULL;
4980     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4981     ok(err != NULL, "expected pointer\n");
4982     if (err)
4983     {
4984         res = 0;
4985         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4986         /* XML_ILLEGAL_TEXT */
4987         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
4988         IXMLDOMParseError_Release(err);
4989     }
4990
4991     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
4992     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4993     err = NULL;
4994     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4995     ok(err != NULL, "expected pointer\n");
4996     if (err)
4997     {
4998         res = 0;
4999         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5000         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5001         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5002         IXMLDOMParseError_Release(err);
5003     }
5004
5005     IXMLDOMDocument2_Release( dtddoc2 );
5006     free_bstrs();
5007 }
5008
5009 #define helper_ole_check(expr) { \
5010     HRESULT r = expr; \
5011     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5012 }
5013
5014 #define helper_expect_list_and_release(list, expstr) { \
5015     char *str = list_to_string(list); \
5016     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5017     if (list) IXMLDOMNodeList_Release(list); \
5018 }
5019
5020 #define helper_expect_bstr_and_release(bstr, str) { \
5021     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5022        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5023     SysFreeString(bstr); \
5024 }
5025
5026 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5027 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5028 {
5029     IXMLDOMNode *node1, *node2;
5030     IXMLDOMNodeList *list;
5031     BSTR bstr;
5032
5033     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5034     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5035     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5036     helper_ole_check(IXMLDOMNodeList_reset(list));
5037     helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
5038
5039     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5040     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");
5041     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5042     if (str)
5043     {
5044         helper_expect_bstr_and_release(bstr, str);
5045     }
5046     else
5047     {
5048         helper_expect_bstr_and_release(bstr, "This is a description.");
5049     }
5050     IXMLDOMNode_Release(node1);
5051
5052     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5053     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");
5054     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5055     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5056     IXMLDOMNode_Release(node2);
5057 }
5058
5059 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5060 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5061 {
5062     IXMLDOMNode *node1, *node2;
5063     IXMLDOMNodeList *list;
5064     BSTR bstr;
5065
5066     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5067     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5068     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5069     helper_ole_check(IXMLDOMNodeList_reset(list));
5070     helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
5071
5072     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5073     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");
5074     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5075     if (str)
5076     {
5077         helper_expect_bstr_and_release(bstr, str);
5078     }
5079     else
5080     {
5081         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5082     }
5083     IXMLDOMNode_Release(node1);
5084
5085     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5086     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");
5087     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5088     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5089     IXMLDOMNode_Release(node2);
5090 }
5091
5092 static void test_whitespace(void)
5093 {
5094     VARIANT_BOOL b;
5095     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5096
5097     doc1 = create_document(&IID_IXMLDOMDocument2);
5098     doc2 = create_document(&IID_IXMLDOMDocument2);
5099     if (!doc1 || !doc2) return;
5100
5101     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5102     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5103     ok(b == VARIANT_FALSE, "expected false\n");
5104     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5105     ok(b == VARIANT_TRUE, "expected true\n");
5106
5107     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5108     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5109     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5110     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5111
5112     /* switch to XPath */
5113     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5114     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5115
5116     check_ws_ignored(doc1, NULL);
5117     check_ws_preserved(doc2, NULL);
5118
5119     /* new instances copy the property */
5120     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5121     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5122
5123     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5124     ok(b == VARIANT_FALSE, "expected false\n");
5125     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5126     ok(b == VARIANT_TRUE, "expected true\n");
5127
5128     check_ws_ignored(doc3, NULL);
5129     check_ws_preserved(doc4, NULL);
5130
5131     /* setting after loading xml affects trimming of leading/trailing ws only */
5132     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5133     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5134
5135     /* the trailing "\n            " isn't there, because it was ws-only node */
5136     check_ws_ignored(doc1, "\n                This is a description. ");
5137     check_ws_preserved(doc2, "This is a description.");
5138
5139     /* it takes effect on reload */
5140     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5141     ok(b == VARIANT_TRUE, "expected true\n");
5142     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5143     ok(b == VARIANT_FALSE, "expected false\n");
5144
5145     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5146     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5147     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5148     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5149
5150     check_ws_preserved(doc1, NULL);
5151     check_ws_ignored(doc2, NULL);
5152
5153     /* other instances follow suit */
5154     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5155     ok(b == VARIANT_TRUE, "expected true\n");
5156     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5157     ok(b == VARIANT_FALSE, "expected false\n");
5158
5159     check_ws_preserved(doc3, NULL);
5160     check_ws_ignored(doc4, NULL);
5161
5162     IXMLDOMDocument_Release(doc1);
5163     IXMLDOMDocument_Release(doc2);
5164     IXMLDOMDocument_Release(doc3);
5165     IXMLDOMDocument_Release(doc4);
5166     free_bstrs();
5167 }
5168
5169 static void test_XPath(void)
5170 {
5171     VARIANT var;
5172     VARIANT_BOOL b;
5173     IXMLDOMDocument2 *doc;
5174     IXMLDOMDocument *doc2;
5175     IXMLDOMNode *rootNode;
5176     IXMLDOMNode *elem1Node;
5177     IXMLDOMNode *node;
5178     IXMLDOMNodeList *list;
5179     IXMLDOMElement *elem;
5180     IXMLDOMAttribute *attr;
5181     HRESULT hr;
5182     BSTR str;
5183
5184     doc = create_document(&IID_IXMLDOMDocument2);
5185     if (!doc) return;
5186
5187     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
5188     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5189
5190     /* switch to XPath */
5191     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5192
5193     /* some simple queries*/
5194     EXPECT_REF(doc, 1);
5195     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5196     EXPECT_HR(hr, S_OK);
5197     EXPECT_REF(doc, 1);
5198     EXPECT_LIST_LEN(list, 1);
5199
5200     EXPECT_REF(list, 1);
5201     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5202     EXPECT_HR(hr, S_OK);
5203     EXPECT_REF(list, 1);
5204     EXPECT_REF(rootNode, 1);
5205
5206     hr = IXMLDOMNodeList_reset(list);
5207     EXPECT_HR(hr, S_OK);
5208     expect_list_and_release(list, "E2.D1");
5209
5210     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5211     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5212
5213     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5214     expect_list_and_release(list, "E3.E2.E2.D1");
5215
5216     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5217     /* using get_item for query results advances the position */
5218     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5219     expect_node(node, "E2.E2.D1");
5220     IXMLDOMNode_Release(node);
5221     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5222     expect_node(node, "E4.E2.D1");
5223     IXMLDOMNode_Release(node);
5224     ole_check(IXMLDOMNodeList_reset(list));
5225     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5226
5227     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5228     expect_list_and_release(list, "E2.D1");
5229
5230     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5231     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5232     ole_check(IXMLDOMNodeList_reset(list));
5233     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5234
5235     /* select an attribute */
5236     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5237     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5238
5239     /* would evaluate to a number */
5240     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5241     /* would evaluate to a boolean */
5242     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5243     /* would evaluate to a string */
5244     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5245
5246     /* no results */
5247     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5248     expect_list_and_release(list, "");
5249     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5250     expect_list_and_release(list, "");
5251     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5252     expect_list_and_release(list, "");
5253     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5254     expect_list_and_release(list, "");
5255
5256     /* foo undeclared in document node */
5257     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5258     /* undeclared in <root> node */
5259     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5260     /* undeclared in <elem> node */
5261     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5262     /* but this trick can be used */
5263     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5264     expect_list_and_release(list, "E3.E4.E2.D1");
5265
5266     /* it has to be declared in SelectionNamespaces */
5267     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5268         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5269
5270     /* now the namespace can be used */
5271     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5272     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5273     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5274     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5275     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5276     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5277     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5278     expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
5279
5280     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5281     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5282         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5283
5284     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5285
5286     VariantInit(&var);
5287     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5288     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5289     if (V_VT(&var) == VT_BSTR)
5290         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5291
5292     /* extra attributes - same thing*/
5293     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5294         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5295     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5296
5297     IXMLDOMNode_Release(rootNode);
5298     IXMLDOMNode_Release(elem1Node);
5299
5300     /* alter document with already built list */
5301     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5302     EXPECT_HR(hr, S_OK);
5303     EXPECT_LIST_LEN(list, 1);
5304
5305     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5306     EXPECT_HR(hr, S_OK);
5307     EXPECT_REF(rootNode, 1);
5308     EXPECT_REF(doc, 1);
5309
5310     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5311     EXPECT_HR(hr, S_OK);
5312     IXMLDOMNode_Release(rootNode);
5313
5314     EXPECT_LIST_LEN(list, 1);
5315
5316     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5317     EXPECT_HR(hr, S_OK);
5318     EXPECT_REF(rootNode, 1);
5319
5320     IXMLDOMNodeList_Release(list);
5321
5322     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5323     EXPECT_HR(hr, S_OK);
5324     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5325     SysFreeString(str);
5326     IXMLDOMNode_Release(rootNode);
5327
5328     /* alter node from list and get it another time */
5329     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5330     EXPECT_HR(hr, S_OK);
5331     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5332
5333     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5334     EXPECT_HR(hr, S_OK);
5335     EXPECT_LIST_LEN(list, 1);
5336
5337     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5338     EXPECT_HR(hr, S_OK);
5339
5340     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5341     EXPECT_HR(hr, S_OK);
5342
5343     V_VT(&var) = VT_I2;
5344     V_I2(&var) = 1;
5345     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5346     EXPECT_HR(hr, S_OK);
5347     IXMLDOMElement_Release(elem);
5348     IXMLDOMNode_Release(rootNode);
5349
5350     /* now check attribute to be present */
5351     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5352     EXPECT_HR(hr, S_OK);
5353
5354     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5355     EXPECT_HR(hr, S_OK);
5356
5357     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5358     EXPECT_HR(hr, S_OK);
5359     IXMLDOMAttribute_Release(attr);
5360
5361     IXMLDOMElement_Release(elem);
5362     IXMLDOMNode_Release(rootNode);
5363
5364     /* and now check for attribute in original document */
5365     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5366     EXPECT_HR(hr, S_OK);
5367
5368     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5369     EXPECT_HR(hr, S_OK);
5370     IXMLDOMAttribute_Release(attr);
5371
5372     IXMLDOMElement_Release(elem);
5373
5374     /* attach node from list to another document */
5375     doc2 = create_document(&IID_IXMLDOMDocument);
5376
5377     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5378     EXPECT_HR(hr, S_OK);
5379     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5380
5381     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5382     EXPECT_HR(hr, S_OK);
5383     EXPECT_LIST_LEN(list, 1);
5384
5385     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5386     EXPECT_HR(hr, S_OK);
5387     EXPECT_REF(rootNode, 1);
5388
5389     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5390     EXPECT_HR(hr, S_OK);
5391     EXPECT_REF(rootNode, 1);
5392     EXPECT_REF(doc2, 1);
5393     EXPECT_REF(list, 1);
5394
5395     EXPECT_LIST_LEN(list, 1);
5396
5397     IXMLDOMNode_Release(rootNode);
5398     IXMLDOMNodeList_Release(list);
5399     IXMLDOMDocument_Release(doc2);
5400
5401     IXMLDOMDocument2_Release(doc);
5402     free_bstrs();
5403 }
5404
5405 static void test_cloneNode(void )
5406 {
5407     IXMLDOMDocument *doc, *doc2;
5408     VARIANT_BOOL b;
5409     IXMLDOMNodeList *pList;
5410     IXMLDOMNamedNodeMap *mapAttr;
5411     LONG length, length1;
5412     LONG attr_cnt, attr_cnt1;
5413     IXMLDOMNode *node;
5414     IXMLDOMNode *node_clone;
5415     IXMLDOMNode *node_first;
5416     HRESULT hr;
5417
5418     doc = create_document(&IID_IXMLDOMDocument);
5419     if (!doc) return;
5420
5421     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5422     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5423
5424     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5425     ok( hr == S_OK, "ret %08x\n", hr );
5426     ok( node != NULL, "node %p\n", node );
5427
5428     /* Check invalid parameter */
5429     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5430     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5431
5432     /* All Children */
5433     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5434     ok( hr == S_OK, "ret %08x\n", hr );
5435     ok( node_clone != NULL, "node %p\n", node );
5436
5437     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5438     ok( hr == S_OK, "ret %08x\n", hr );
5439     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5440     ok( hr == S_OK, "ret %08x\n", hr );
5441     IXMLDOMDocument_Release(doc2);
5442     IXMLDOMNode_Release(node_first);
5443
5444     hr = IXMLDOMNode_get_childNodes(node, &pList);
5445     ok( hr == S_OK, "ret %08x\n", hr );
5446     length = 0;
5447     hr = IXMLDOMNodeList_get_length(pList, &length);
5448     ok( hr == S_OK, "ret %08x\n", hr );
5449     ok(length == 1, "got %d\n", length);
5450     IXMLDOMNodeList_Release(pList);
5451
5452     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5453     ok( hr == S_OK, "ret %08x\n", hr );
5454     attr_cnt = 0;
5455     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5456     ok( hr == S_OK, "ret %08x\n", hr );
5457     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5458     IXMLDOMNamedNodeMap_Release(mapAttr);
5459
5460     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5461     ok( hr == S_OK, "ret %08x\n", hr );
5462     length1 = 0;
5463     hr = IXMLDOMNodeList_get_length(pList, &length1);
5464     ok(length1 == 1, "got %d\n", length1);
5465     ok( hr == S_OK, "ret %08x\n", hr );
5466     IXMLDOMNodeList_Release(pList);
5467
5468     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5469     ok( hr == S_OK, "ret %08x\n", hr );
5470     attr_cnt1 = 0;
5471     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5472     ok( hr == S_OK, "ret %08x\n", hr );
5473     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5474     IXMLDOMNamedNodeMap_Release(mapAttr);
5475
5476     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5477     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5478     IXMLDOMNode_Release(node_clone);
5479
5480     /* No Children */
5481     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5482     ok( hr == S_OK, "ret %08x\n", hr );
5483     ok( node_clone != NULL, "node %p\n", node );
5484
5485     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5486     ok(hr == S_FALSE, "ret %08x\n", hr );
5487
5488     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5489     ok(hr == S_OK, "ret %08x\n", hr );
5490     hr = IXMLDOMNodeList_get_length(pList, &length1);
5491     ok(hr == S_OK, "ret %08x\n", hr );
5492     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5493     IXMLDOMNodeList_Release(pList);
5494
5495     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5496     ok(hr == S_OK, "ret %08x\n", hr );
5497     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5498     ok(hr == S_OK, "ret %08x\n", hr );
5499     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5500     IXMLDOMNamedNodeMap_Release(mapAttr);
5501
5502     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5503     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5504     IXMLDOMNode_Release(node_clone);
5505
5506     IXMLDOMNode_Release(node);
5507     IXMLDOMDocument_Release(doc);
5508     free_bstrs();
5509 }
5510
5511 static void test_xmlTypes(void)
5512 {
5513     IXMLDOMDocument *doc;
5514     IXMLDOMElement *pRoot;
5515     HRESULT hr;
5516     IXMLDOMComment *pComment;
5517     IXMLDOMElement *pElement;
5518     IXMLDOMAttribute *pAttribute;
5519     IXMLDOMNamedNodeMap *pAttribs;
5520     IXMLDOMCDATASection *pCDataSec;
5521     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5522     IXMLDOMDocumentFragment *pDocFrag = NULL;
5523     IXMLDOMEntityReference *pEntityRef = NULL;
5524     BSTR str;
5525     IXMLDOMNode *pNextChild;
5526     VARIANT v;
5527     LONG len = 0;
5528
5529     doc = create_document(&IID_IXMLDOMDocument);
5530     if (!doc) return;
5531
5532     pNextChild = (void*)0xdeadbeef;
5533     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5534     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5535
5536     pNextChild = (void*)0xdeadbeef;
5537     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5538     ok(hr == S_FALSE, "ret %08x\n", hr );
5539     ok(pNextChild == NULL, "pDocChild not NULL\n");
5540
5541     /* test previous Sibling */
5542     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5543     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5544
5545     pNextChild = (void*)0xdeadbeef;
5546     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5547     ok(hr == S_FALSE, "ret %08x\n", hr );
5548     ok(pNextChild == NULL, "pNextChild not NULL\n");
5549
5550     /* test get_dataType */
5551     V_VT(&v) = VT_EMPTY;
5552     hr = IXMLDOMDocument_get_dataType(doc, &v);
5553     ok(hr == S_FALSE, "ret %08x\n", hr );
5554     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5555     VariantClear(&v);
5556
5557     /* test implementation */
5558     hr = IXMLDOMDocument_get_implementation(doc, NULL);
5559     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5560
5561     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5562     ok(hr == S_OK, "ret %08x\n", hr );
5563     if(hr == S_OK)
5564     {
5565         VARIANT_BOOL hasFeature = VARIANT_TRUE;
5566         BSTR sEmpty = SysAllocStringLen(NULL, 0);
5567
5568         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5569         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5570
5571         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5572         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5573
5574         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5575         ok(hr == S_OK, "ret %08x\n", hr );
5576         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5577
5578         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5579         ok(hr == S_OK, "ret %08x\n", hr );
5580         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5581
5582         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5583         ok(hr == S_OK, "ret %08x\n", hr );
5584         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5585
5586         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5587         ok(hr == S_OK, "ret %08x\n", hr );
5588         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5589
5590         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5591         ok(hr == S_OK, "ret %08x\n", hr );
5592         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5593
5594         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5595         ok(hr == S_OK, "ret %08x\n", hr );
5596         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5597
5598         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5599         ok(hr == S_OK, "ret %08x\n", hr );
5600         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5601
5602         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5603         ok(hr == S_OK, "ret %08x\n", hr );
5604         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5605
5606         SysFreeString(sEmpty);
5607         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5608     }
5609
5610     pRoot = (IXMLDOMElement*)0x1;
5611     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5612     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5613     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5614
5615     pRoot = (IXMLDOMElement*)0x1;
5616     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5617     ok(hr == E_FAIL, "ret %08x\n", hr );
5618     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5619
5620     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5621     ok(hr == S_OK, "ret %08x\n", hr );
5622     if(hr == S_OK)
5623     {
5624         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5625         ok(hr == S_OK, "ret %08x\n", hr );
5626         if(hr == S_OK)
5627         {
5628             /* Comment */
5629             str = SysAllocString(szComment);
5630             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5631             SysFreeString(str);
5632             ok(hr == S_OK, "ret %08x\n", hr );
5633             if(hr == S_OK)
5634             {
5635                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5636                 ok(hr == S_OK, "ret %08x\n", hr );
5637
5638                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5639                 ok(hr == S_OK, "ret %08x\n", hr );
5640                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
5641                 SysFreeString(str);
5642
5643                 hr = IXMLDOMComment_get_xml(pComment, &str);
5644                 ok(hr == S_OK, "ret %08x\n", hr );
5645                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
5646                 SysFreeString(str);
5647
5648                 /* put data Tests */
5649                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5650                 ok(hr == S_OK, "ret %08x\n", hr );
5651
5652                 /* get data Tests */
5653                 hr = IXMLDOMComment_get_data(pComment, &str);
5654                 ok(hr == S_OK, "ret %08x\n", hr );
5655                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
5656                 SysFreeString(str);
5657
5658                 /* get data Tests */
5659                 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
5660                 ok(hr == S_OK, "ret %08x\n", hr );
5661                 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
5662                 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
5663                 VariantClear(&v);
5664
5665                 /* Confirm XML text is good */
5666                 hr = IXMLDOMComment_get_xml(pComment, &str);
5667                 ok(hr == S_OK, "ret %08x\n", hr );
5668                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
5669                 SysFreeString(str);
5670
5671                 /* Confirm we get the put_data Text back */
5672                 hr = IXMLDOMComment_get_text(pComment, &str);
5673                 ok(hr == S_OK, "ret %08x\n", hr );
5674                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
5675                 SysFreeString(str);
5676
5677                 /* test length property */
5678                 hr = IXMLDOMComment_get_length(pComment, &len);
5679                 ok(hr == S_OK, "ret %08x\n", hr );
5680                 ok(len == 21, "expected 21 got %d\n", len);
5681
5682                 /* test substringData */
5683                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5684                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5685
5686                 /* test substringData - Invalid offset */
5687                 str = (BSTR)&szElement;
5688                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5689                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5690                 ok( str == NULL, "incorrect string\n");
5691
5692                 /* test substringData - Invalid offset */
5693                 str = (BSTR)&szElement;
5694                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5695                 ok(hr == S_FALSE, "ret %08x\n", hr );
5696                 ok( str == NULL, "incorrect string\n");
5697
5698                 /* test substringData - Invalid size */
5699                 str = (BSTR)&szElement;
5700                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5701                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5702                 ok( str == NULL, "incorrect string\n");
5703
5704                 /* test substringData - Invalid size */
5705                 str = (BSTR)&szElement;
5706                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5707                 ok(hr == S_FALSE, "ret %08x\n", hr );
5708                 ok( str == NULL, "incorrect string\n");
5709
5710                 /* test substringData - Start of string */
5711                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5712                 ok(hr == S_OK, "ret %08x\n", hr );
5713                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5714                 SysFreeString(str);
5715
5716                 /* test substringData - Middle of string */
5717                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5718                 ok(hr == S_OK, "ret %08x\n", hr );
5719                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5720                 SysFreeString(str);
5721
5722                 /* test substringData - End of string */
5723                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5724                 ok(hr == S_OK, "ret %08x\n", hr );
5725                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5726                 SysFreeString(str);
5727
5728                 /* test appendData */
5729                 hr = IXMLDOMComment_appendData(pComment, NULL);
5730                 ok(hr == S_OK, "ret %08x\n", hr );
5731
5732                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5733                 ok(hr == S_OK, "ret %08x\n", hr );
5734
5735                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5736                 ok(hr == S_OK, "ret %08x\n", hr );
5737
5738                 hr = IXMLDOMComment_get_text(pComment, &str);
5739                 ok(hr == S_OK, "ret %08x\n", hr );
5740                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5741                 SysFreeString(str);
5742
5743                 /* test insertData */
5744                 str = SysAllocStringLen(NULL, 0);
5745                 hr = IXMLDOMComment_insertData(pComment, -1, str);
5746                 ok(hr == S_OK, "ret %08x\n", hr );
5747
5748                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5749                 ok(hr == S_OK, "ret %08x\n", hr );
5750
5751                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5752                 ok(hr == S_OK, "ret %08x\n", hr );
5753
5754                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5755                 ok(hr == S_OK, "ret %08x\n", hr );
5756
5757                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5758                 ok(hr == S_OK, "ret %08x\n", hr );
5759
5760                 hr = IXMLDOMComment_insertData(pComment, 0, str);
5761                 ok(hr == S_OK, "ret %08x\n", hr );
5762                 SysFreeString(str);
5763
5764                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5765                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5766
5767                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5768                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5769
5770                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5771                 ok(hr == S_OK, "ret %08x\n", hr );
5772
5773                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5774                 ok(hr == S_OK, "ret %08x\n", hr );
5775
5776                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5777                 ok(hr == S_OK, "ret %08x\n", hr );
5778
5779                 hr = IXMLDOMComment_get_text(pComment, &str);
5780                 ok(hr == S_OK, "ret %08x\n", hr );
5781                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5782                 SysFreeString(str);
5783
5784                 /* delete data */
5785                 /* invalid arguments */
5786                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
5787                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5788
5789                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
5790                 ok(hr == S_OK, "ret %08x\n", hr );
5791
5792                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
5793                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5794
5795                 hr = IXMLDOMComment_get_length(pComment, &len);
5796                 ok(hr == S_OK, "ret %08x\n", hr );
5797                 ok(len == 43, "expected 43 got %d\n", len);
5798
5799                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
5800                 ok(hr == S_OK, "ret %08x\n", hr );
5801
5802                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
5803                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5804
5805                 /* delete from start */
5806                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
5807                 ok(hr == S_OK, "ret %08x\n", hr );
5808
5809                 hr = IXMLDOMComment_get_length(pComment, &len);
5810                 ok(hr == S_OK, "ret %08x\n", hr );
5811                 ok(len == 38, "expected 38 got %d\n", len);
5812
5813                 hr = IXMLDOMComment_get_text(pComment, &str);
5814                 ok(hr == S_OK, "ret %08x\n", hr );
5815                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5816                 SysFreeString(str);
5817
5818                 /* delete from end */
5819                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
5820                 ok(hr == S_OK, "ret %08x\n", hr );
5821
5822                 hr = IXMLDOMComment_get_length(pComment, &len);
5823                 ok(hr == S_OK, "ret %08x\n", hr );
5824                 ok(len == 35, "expected 35 got %d\n", len);
5825
5826                 hr = IXMLDOMComment_get_text(pComment, &str);
5827                 ok(hr == S_OK, "ret %08x\n", hr );
5828                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5829                 SysFreeString(str);
5830
5831                 /* delete from inside */
5832                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
5833                 ok(hr == S_OK, "ret %08x\n", hr );
5834
5835                 hr = IXMLDOMComment_get_length(pComment, &len);
5836                 ok(hr == S_OK, "ret %08x\n", hr );
5837                 ok(len == 2, "expected 2 got %d\n", len);
5838
5839                 hr = IXMLDOMComment_get_text(pComment, &str);
5840                 ok(hr == S_OK, "ret %08x\n", hr );
5841                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5842                 SysFreeString(str);
5843
5844                 /* delete whole data ... */
5845                 hr = IXMLDOMComment_get_length(pComment, &len);
5846                 ok(hr == S_OK, "ret %08x\n", hr );
5847
5848                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5849                 ok(hr == S_OK, "ret %08x\n", hr );
5850                 /* ... and try again with empty string */
5851                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5852                 ok(hr == S_OK, "ret %08x\n", hr );
5853
5854                 /* ::replaceData() */
5855                 V_VT(&v) = VT_BSTR;
5856                 V_BSTR(&v) = SysAllocString(szstr1);
5857                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
5858                 ok(hr == S_OK, "ret %08x\n", hr );
5859                 VariantClear(&v);
5860
5861                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
5862                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5863                 hr = IXMLDOMComment_get_text(pComment, &str);
5864                 ok(hr == S_OK, "ret %08x\n", hr );
5865                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5866                 SysFreeString(str);
5867
5868                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
5869                 ok(hr == S_OK, "ret %08x\n", hr );
5870                 hr = IXMLDOMComment_get_text(pComment, &str);
5871                 ok(hr == S_OK, "ret %08x\n", hr );
5872                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5873                 SysFreeString(str);
5874
5875                 /* NULL pointer means delete */
5876                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
5877                 ok(hr == S_OK, "ret %08x\n", hr );
5878                 hr = IXMLDOMComment_get_text(pComment, &str);
5879                 ok(hr == S_OK, "ret %08x\n", hr );
5880                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5881                 SysFreeString(str);
5882
5883                 /* empty string means delete */
5884                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
5885                 ok(hr == S_OK, "ret %08x\n", hr );
5886                 hr = IXMLDOMComment_get_text(pComment, &str);
5887                 ok(hr == S_OK, "ret %08x\n", hr );
5888                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5889                 SysFreeString(str);
5890
5891                 /* zero count means insert */
5892                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
5893                 ok(hr == S_OK, "ret %08x\n", hr );
5894                 hr = IXMLDOMComment_get_text(pComment, &str);
5895                 ok(hr == S_OK, "ret %08x\n", hr );
5896                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5897                 SysFreeString(str);
5898
5899                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
5900                 ok(hr == S_OK, "ret %08x\n", hr );
5901
5902                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
5903                 ok(hr == S_OK, "ret %08x\n", hr );
5904                 hr = IXMLDOMComment_get_text(pComment, &str);
5905                 ok(hr == S_OK, "ret %08x\n", hr );
5906                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5907                 SysFreeString(str);
5908
5909                 /* nonempty string, count greater than its length */
5910                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
5911                 ok(hr == S_OK, "ret %08x\n", hr );
5912                 hr = IXMLDOMComment_get_text(pComment, &str);
5913                 ok(hr == S_OK, "ret %08x\n", hr );
5914                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5915                 SysFreeString(str);
5916
5917                 /* nonempty string, count less than its length */
5918                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
5919                 ok(hr == S_OK, "ret %08x\n", hr );
5920                 hr = IXMLDOMComment_get_text(pComment, &str);
5921                 ok(hr == S_OK, "ret %08x\n", hr );
5922                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5923                 SysFreeString(str);
5924
5925                 IXMLDOMComment_Release(pComment);
5926             }
5927
5928             /* Element */
5929             str = SysAllocString(szElement);
5930             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
5931             SysFreeString(str);
5932             ok(hr == S_OK, "ret %08x\n", hr );
5933             if(hr == S_OK)
5934             {
5935                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5936                 ok(hr == S_OK, "ret %08x\n", hr );
5937
5938                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
5939                 ok(hr == S_OK, "ret %08x\n", hr );
5940                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
5941                 SysFreeString(str);
5942
5943                 hr = IXMLDOMElement_get_xml(pElement, &str);
5944                 ok(hr == S_OK, "ret %08x\n", hr );
5945                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
5946                 SysFreeString(str);
5947
5948                 /* Attribute */
5949                 pAttribute = (IXMLDOMAttribute*)0x1;
5950                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
5951                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5952                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5953
5954                 pAttribute = (IXMLDOMAttribute*)0x1;
5955                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
5956                 ok(hr == E_FAIL, "ret %08x\n", hr );
5957                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5958
5959                 str = SysAllocString(szAttribute);
5960                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
5961                 SysFreeString(str);
5962                 ok(hr == S_OK, "ret %08x\n", hr );
5963                 if(hr == S_OK)
5964                 {
5965                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
5966
5967                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
5968                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5969
5970                     pNextChild = (IXMLDOMNode *)0x1;
5971                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
5972                     ok(hr == S_FALSE, "ret %08x\n", hr );
5973                     ok(pNextChild == NULL, "pNextChild not NULL\n");
5974
5975                     /* test Previous Sibling*/
5976                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
5977                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5978
5979                     pNextChild = (IXMLDOMNode *)0x1;
5980                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
5981                     ok(hr == S_FALSE, "ret %08x\n", hr );
5982                     ok(pNextChild == NULL, "pNextChild not NULL\n");
5983
5984                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
5985                     ok(hr == E_FAIL, "ret %08x\n", hr );
5986                     ok(pNewChild == NULL, "pNewChild not NULL\n");
5987
5988                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
5989                     ok(hr == S_OK, "ret %08x\n", hr );
5990                     if ( hr == S_OK )
5991                     {
5992                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
5993                         ok(hr == S_OK, "ret %08x\n", hr );
5994
5995                         IXMLDOMNamedNodeMap_Release(pAttribs);
5996                     }
5997
5998                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5999                     ok(hr == S_OK, "ret %08x\n", hr );
6000                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6001                     SysFreeString(str);
6002
6003                     /* test nodeName */
6004                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6005                     ok(hr == S_OK, "ret %08x\n", hr );
6006                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6007                     SysFreeString(str);
6008
6009                     /* test name property */
6010                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6011                     ok(hr == S_OK, "ret %08x\n", hr );
6012                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6013                     SysFreeString(str);
6014
6015                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6016                     ok(hr == S_OK, "ret %08x\n", hr );
6017                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6018                     SysFreeString(str);
6019
6020                     IXMLDOMAttribute_Release(pAttribute);
6021
6022                     /* Check Element again with the Add Attribute*/
6023                     hr = IXMLDOMElement_get_xml(pElement, &str);
6024                     ok(hr == S_OK, "ret %08x\n", hr );
6025                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6026                     SysFreeString(str);
6027                 }
6028
6029                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6030                 ok(hr == S_OK, "ret %08x\n", hr );
6031
6032                 hr = IXMLDOMElement_get_xml(pElement, &str);
6033                 ok(hr == S_OK, "ret %08x\n", hr );
6034                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6035                 SysFreeString(str);
6036
6037                 /* Test for reversible escaping */
6038                 str = SysAllocString( szStrangeChars );
6039                 hr = IXMLDOMElement_put_text(pElement, str);
6040                 ok(hr == S_OK, "ret %08x\n", hr );
6041                 SysFreeString( str );
6042
6043                 hr = IXMLDOMElement_get_xml(pElement, &str);
6044                 ok(hr == S_OK, "ret %08x\n", hr );
6045                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6046                 SysFreeString(str);
6047
6048                 hr = IXMLDOMElement_get_text(pElement, &str);
6049                 ok(hr == S_OK, "ret %08x\n", hr );
6050                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6051                 SysFreeString(str);
6052
6053                 IXMLDOMElement_Release(pElement);
6054             }
6055
6056             /* CData Section */
6057             str = SysAllocString(szCData);
6058             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6059             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6060
6061             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6062             SysFreeString(str);
6063             ok(hr == S_OK, "ret %08x\n", hr );
6064             if(hr == S_OK)
6065             {
6066                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6067                 VARIANT var;
6068
6069                 VariantInit(&var);
6070
6071                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6072                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6073
6074                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6075                 ok(hr == S_OK, "ret %08x\n", hr );
6076
6077                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6078                 ok(hr == S_OK, "ret %08x\n", hr );
6079                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6080                 SysFreeString(str);
6081
6082                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6083                 ok(hr == S_OK, "ret %08x\n", hr );
6084                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6085                 SysFreeString(str);
6086
6087                 /* test lastChild */
6088                 pNextChild = (IXMLDOMNode*)0x1;
6089                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6090                 ok(hr == S_FALSE, "ret %08x\n", hr );
6091                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6092
6093                 /* put data Tests */
6094                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6095                 ok(hr == S_OK, "ret %08x\n", hr );
6096
6097                 /* Confirm XML text is good */
6098                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6099                 ok(hr == S_OK, "ret %08x\n", hr );
6100                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6101                 SysFreeString(str);
6102
6103                 /* Confirm we get the put_data Text back */
6104                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6105                 ok(hr == S_OK, "ret %08x\n", hr );
6106                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6107                 SysFreeString(str);
6108
6109                 /* test length property */
6110                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6111                 ok(hr == S_OK, "ret %08x\n", hr );
6112                 ok(len == 21, "expected 21 got %d\n", len);
6113
6114                 /* test get nodeValue */
6115                 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
6116                 ok(hr == S_OK, "ret %08x\n", hr );
6117                 ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var));
6118                 ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6119                 VariantClear(&var);
6120
6121                 /* test get data */
6122                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6123                 ok(hr == S_OK, "ret %08x\n", hr );
6124                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6125                 SysFreeString(str);
6126
6127                 /* test substringData */
6128                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6129                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6130
6131                 /* test substringData - Invalid offset */
6132                 str = (BSTR)&szElement;
6133                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6134                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6135                 ok( str == NULL, "incorrect string\n");
6136
6137                 /* test substringData - Invalid offset */
6138                 str = (BSTR)&szElement;
6139                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6140                 ok(hr == S_FALSE, "ret %08x\n", hr );
6141                 ok( str == NULL, "incorrect string\n");
6142
6143                 /* test substringData - Invalid size */
6144                 str = (BSTR)&szElement;
6145                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6146                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6147                 ok( str == NULL, "incorrect string\n");
6148
6149                 /* test substringData - Invalid size */
6150                 str = (BSTR)&szElement;
6151                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6152                 ok(hr == S_FALSE, "ret %08x\n", hr );
6153                 ok( str == NULL, "incorrect string\n");
6154
6155                 /* test substringData - Start of string */
6156                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6157                 ok(hr == S_OK, "ret %08x\n", hr );
6158                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6159                 SysFreeString(str);
6160
6161                 /* test substringData - Middle of string */
6162                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6163                 ok(hr == S_OK, "ret %08x\n", hr );
6164                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6165                 SysFreeString(str);
6166
6167                 /* test substringData - End of string */
6168                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6169                 ok(hr == S_OK, "ret %08x\n", hr );
6170                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6171                 SysFreeString(str);
6172
6173                 /* test appendData */
6174                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6175                 ok(hr == S_OK, "ret %08x\n", hr );
6176
6177                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6178                 ok(hr == S_OK, "ret %08x\n", hr );
6179
6180                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6181                 ok(hr == S_OK, "ret %08x\n", hr );
6182
6183                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6184                 ok(hr == S_OK, "ret %08x\n", hr );
6185                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6186                 SysFreeString(str);
6187
6188                 /* test insertData */
6189                 str = SysAllocStringLen(NULL, 0);
6190                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6191                 ok(hr == S_OK, "ret %08x\n", hr );
6192
6193                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6194                 ok(hr == S_OK, "ret %08x\n", hr );
6195
6196                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6197                 ok(hr == S_OK, "ret %08x\n", hr );
6198
6199                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6200                 ok(hr == S_OK, "ret %08x\n", hr );
6201
6202                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6203                 ok(hr == S_OK, "ret %08x\n", hr );
6204
6205                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6206                 ok(hr == S_OK, "ret %08x\n", hr );
6207                 SysFreeString(str);
6208
6209                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6210                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6211
6212                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6213                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6214
6215                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6216                 ok(hr == S_OK, "ret %08x\n", hr );
6217
6218                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6219                 ok(hr == S_OK, "ret %08x\n", hr );
6220
6221                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6222                 ok(hr == S_OK, "ret %08x\n", hr );
6223
6224                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6225                 ok(hr == S_OK, "ret %08x\n", hr );
6226                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6227                 SysFreeString(str);
6228
6229                 /* delete data */
6230                 /* invalid arguments */
6231                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6232                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6233
6234                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6235                 ok(hr == S_OK, "ret %08x\n", hr );
6236
6237                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6238                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6239
6240                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6241                 ok(hr == S_OK, "ret %08x\n", hr );
6242                 ok(len == 43, "expected 43 got %d\n", len);
6243
6244                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6245                 ok(hr == S_OK, "ret %08x\n", hr );
6246
6247                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6248                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6249
6250                 /* delete from start */
6251                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6252                 ok(hr == S_OK, "ret %08x\n", hr );
6253
6254                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6255                 ok(hr == S_OK, "ret %08x\n", hr );
6256                 ok(len == 38, "expected 38 got %d\n", len);
6257
6258                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6259                 ok(hr == S_OK, "ret %08x\n", hr );
6260                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6261                 SysFreeString(str);
6262
6263                 /* delete from end */
6264                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6265                 ok(hr == S_OK, "ret %08x\n", hr );
6266
6267                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6268                 ok(hr == S_OK, "ret %08x\n", hr );
6269                 ok(len == 35, "expected 35 got %d\n", len);
6270
6271                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6272                 ok(hr == S_OK, "ret %08x\n", hr );
6273                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6274                 SysFreeString(str);
6275
6276                 /* delete from inside */
6277                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6278                 ok(hr == S_OK, "ret %08x\n", hr );
6279
6280                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6281                 ok(hr == S_OK, "ret %08x\n", hr );
6282                 ok(len == 2, "expected 2 got %d\n", len);
6283
6284                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6285                 ok(hr == S_OK, "ret %08x\n", hr );
6286                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6287                 SysFreeString(str);
6288
6289                 /* delete whole data ... */
6290                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6291                 ok(hr == S_OK, "ret %08x\n", hr );
6292
6293                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6294                 ok(hr == S_OK, "ret %08x\n", hr );
6295
6296                 /* ... and try again with empty string */
6297                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6298                 ok(hr == S_OK, "ret %08x\n", hr );
6299
6300                 /* ::replaceData() */
6301                 V_VT(&v) = VT_BSTR;
6302                 V_BSTR(&v) = SysAllocString(szstr1);
6303                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6304                 ok(hr == S_OK, "ret %08x\n", hr );
6305                 VariantClear(&v);
6306
6307                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6308                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6309                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6310                 ok(hr == S_OK, "ret %08x\n", hr );
6311                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6312                 SysFreeString(str);
6313
6314                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6315                 ok(hr == S_OK, "ret %08x\n", hr );
6316                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6317                 ok(hr == S_OK, "ret %08x\n", hr );
6318                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6319                 SysFreeString(str);
6320
6321                 /* NULL pointer means delete */
6322                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6323                 ok(hr == S_OK, "ret %08x\n", hr );
6324                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6325                 ok(hr == S_OK, "ret %08x\n", hr );
6326                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6327                 SysFreeString(str);
6328
6329                 /* empty string means delete */
6330                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6331                 ok(hr == S_OK, "ret %08x\n", hr );
6332                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6333                 ok(hr == S_OK, "ret %08x\n", hr );
6334                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6335                 SysFreeString(str);
6336
6337                 /* zero count means insert */
6338                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6339                 ok(hr == S_OK, "ret %08x\n", hr );
6340                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6341                 ok(hr == S_OK, "ret %08x\n", hr );
6342                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6343                 SysFreeString(str);
6344
6345                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6346                 ok(hr == S_OK, "ret %08x\n", hr );
6347
6348                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6349                 ok(hr == S_OK, "ret %08x\n", hr );
6350                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6351                 ok(hr == S_OK, "ret %08x\n", hr );
6352                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6353                 SysFreeString(str);
6354
6355                 /* nonempty string, count greater than its length */
6356                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6357                 ok(hr == S_OK, "ret %08x\n", hr );
6358                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6359                 ok(hr == S_OK, "ret %08x\n", hr );
6360                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6361                 SysFreeString(str);
6362
6363                 /* nonempty string, count less than its length */
6364                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6365                 ok(hr == S_OK, "ret %08x\n", hr );
6366                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6367                 ok(hr == S_OK, "ret %08x\n", hr );
6368                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6369                 SysFreeString(str);
6370
6371                 IXMLDOMCDATASection_Release(pCDataSec);
6372             }
6373
6374             /* Document Fragments */
6375             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6376             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6377
6378             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6379             ok(hr == S_OK, "ret %08x\n", hr );
6380             if(hr == S_OK)
6381             {
6382                 IXMLDOMNode *node;
6383
6384                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6385                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6386
6387                 node = (IXMLDOMNode *)0x1;
6388                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6389                 ok(hr == S_FALSE, "ret %08x\n", hr );
6390                 ok(node == NULL, "expected NULL, got %p\n", node);
6391
6392                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6393                 ok(hr == S_OK, "ret %08x\n", hr );
6394
6395                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6396                 ok(hr == S_OK, "ret %08x\n", hr );
6397                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6398                 SysFreeString(str);
6399
6400                 /* test next Sibling*/
6401                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6402                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6403
6404                 node = (IXMLDOMNode *)0x1;
6405                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6406                 ok(hr == S_FALSE, "ret %08x\n", hr );
6407                 ok(node == NULL, "next sibling not NULL\n");
6408
6409                 /* test Previous Sibling*/
6410                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6411                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6412
6413                 node = (IXMLDOMNode *)0x1;
6414                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6415                 ok(hr == S_FALSE, "ret %08x\n", hr );
6416                 ok(node == NULL, "previous sibling not NULL\n");
6417
6418                 IXMLDOMDocumentFragment_Release(pDocFrag);
6419             }
6420
6421             /* Entity References */
6422             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6423             ok(hr == E_FAIL, "ret %08x\n", hr );
6424             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6425             ok(hr == E_FAIL, "ret %08x\n", hr );
6426
6427             str = SysAllocString(szEntityRef);
6428             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6429             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6430
6431             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6432             SysFreeString(str);
6433             ok(hr == S_OK, "ret %08x\n", hr );
6434             if(hr == S_OK)
6435             {
6436                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6437                 ok(hr == S_OK, "ret %08x\n", hr );
6438
6439                 /* test get_xml*/
6440                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6441                 ok(hr == S_OK, "ret %08x\n", hr );
6442                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6443                 SysFreeString(str);
6444
6445                 IXMLDOMEntityReference_Release(pEntityRef);
6446             }
6447
6448             IXMLDOMElement_Release( pRoot );
6449         }
6450     }
6451
6452     IXMLDOMDocument_Release(doc);
6453
6454     free_bstrs();
6455 }
6456
6457 static void test_nodeTypeTests( void )
6458 {
6459     IXMLDOMDocument *doc = NULL;
6460     IXMLDOMElement *pRoot;
6461     IXMLDOMElement *pElement;
6462     HRESULT hr;
6463
6464     doc = create_document(&IID_IXMLDOMDocument);
6465     if (!doc) return;
6466
6467     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6468     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6469
6470     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6471     ok(hr == S_OK, "ret %08x\n", hr );
6472     if(hr == S_OK)
6473     {
6474         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6475         ok(hr == S_OK, "ret %08x\n", hr );
6476         if(hr == S_OK)
6477         {
6478             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
6479             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6480
6481             /* Invalid Value */
6482             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
6483             ok(hr == E_FAIL, "ret %08x\n", hr );
6484
6485             /* NOTE:
6486              *   The name passed into put_dataType is case-insensitive. So many of the names
6487              *     have been changed to reflect this.
6488              */
6489             /* Boolean */
6490             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
6491             ok(hr == S_OK, "ret %08x\n", hr );
6492             if(hr == S_OK)
6493             {
6494                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6495
6496                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
6497                 ok(hr == S_OK, "ret %08x\n", hr );
6498
6499                 IXMLDOMElement_Release(pElement);
6500             }
6501
6502             /* String */
6503             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
6504             ok(hr == S_OK, "ret %08x\n", hr );
6505             if(hr == S_OK)
6506             {
6507                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6508
6509                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
6510                 ok(hr == S_OK, "ret %08x\n", hr );
6511
6512                 IXMLDOMElement_Release(pElement);
6513             }
6514
6515             /* Number */
6516             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
6517             ok(hr == S_OK, "ret %08x\n", hr );
6518             if(hr == S_OK)
6519             {
6520                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6521
6522                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
6523                 ok(hr == S_OK, "ret %08x\n", hr );
6524
6525                 IXMLDOMElement_Release(pElement);
6526             }
6527
6528             /* Int */
6529             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
6530             ok(hr == S_OK, "ret %08x\n", hr );
6531             if(hr == S_OK)
6532             {
6533                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6534
6535                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
6536                 ok(hr == S_OK, "ret %08x\n", hr );
6537
6538                 IXMLDOMElement_Release(pElement);
6539             }
6540
6541             /* Fixed */
6542             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
6543             ok(hr == S_OK, "ret %08x\n", hr );
6544             if(hr == S_OK)
6545             {
6546                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6547
6548                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
6549                 ok(hr == S_OK, "ret %08x\n", hr );
6550
6551                 IXMLDOMElement_Release(pElement);
6552             }
6553
6554             /* DateTime */
6555             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
6556             ok(hr == S_OK, "ret %08x\n", hr );
6557             if(hr == S_OK)
6558             {
6559                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6560
6561                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
6562                 ok(hr == S_OK, "ret %08x\n", hr );
6563
6564                 IXMLDOMElement_Release(pElement);
6565             }
6566
6567             /* DateTime TZ */
6568             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
6569             ok(hr == S_OK, "ret %08x\n", hr );
6570             if(hr == S_OK)
6571             {
6572                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6573
6574                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6575                 ok(hr == S_OK, "ret %08x\n", hr );
6576
6577                 IXMLDOMElement_Release(pElement);
6578             }
6579
6580             /* Date */
6581             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
6582             ok(hr == S_OK, "ret %08x\n", hr );
6583             if(hr == S_OK)
6584             {
6585                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6586
6587                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
6588                 ok(hr == S_OK, "ret %08x\n", hr );
6589
6590                 IXMLDOMElement_Release(pElement);
6591             }
6592
6593             /* Time */
6594             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
6595             ok(hr == S_OK, "ret %08x\n", hr );
6596             if(hr == S_OK)
6597             {
6598                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6599
6600                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
6601                 ok(hr == S_OK, "ret %08x\n", hr );
6602
6603                 IXMLDOMElement_Release(pElement);
6604             }
6605
6606             /* Time.tz */
6607             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
6608             ok(hr == S_OK, "ret %08x\n", hr );
6609             if(hr == S_OK)
6610             {
6611                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6612
6613                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
6614                 ok(hr == S_OK, "ret %08x\n", hr );
6615
6616                 IXMLDOMElement_Release(pElement);
6617             }
6618
6619             /* I1 */
6620             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
6621             ok(hr == S_OK, "ret %08x\n", hr );
6622             if(hr == S_OK)
6623             {
6624                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6625
6626                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
6627                 ok(hr == S_OK, "ret %08x\n", hr );
6628
6629                 IXMLDOMElement_Release(pElement);
6630             }
6631
6632             /* I2 */
6633             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
6634             ok(hr == S_OK, "ret %08x\n", hr );
6635             if(hr == S_OK)
6636             {
6637                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6638
6639                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
6640                 ok(hr == S_OK, "ret %08x\n", hr );
6641
6642                 IXMLDOMElement_Release(pElement);
6643             }
6644
6645             /* I4 */
6646             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
6647             ok(hr == S_OK, "ret %08x\n", hr );
6648             if(hr == S_OK)
6649             {
6650                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6651
6652                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
6653                 ok(hr == S_OK, "ret %08x\n", hr );
6654
6655                 IXMLDOMElement_Release(pElement);
6656             }
6657
6658             /* UI1 */
6659             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
6660             ok(hr == S_OK, "ret %08x\n", hr );
6661             if(hr == S_OK)
6662             {
6663                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6664
6665                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
6666                 ok(hr == S_OK, "ret %08x\n", hr );
6667
6668                 IXMLDOMElement_Release(pElement);
6669             }
6670
6671             /* UI2 */
6672             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
6673             ok(hr == S_OK, "ret %08x\n", hr );
6674             if(hr == S_OK)
6675             {
6676                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6677
6678                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
6679                 ok(hr == S_OK, "ret %08x\n", hr );
6680
6681                 IXMLDOMElement_Release(pElement);
6682             }
6683
6684             /* UI4 */
6685             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
6686             ok(hr == S_OK, "ret %08x\n", hr );
6687             if(hr == S_OK)
6688             {
6689                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6690
6691                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
6692                 ok(hr == S_OK, "ret %08x\n", hr );
6693
6694                 IXMLDOMElement_Release(pElement);
6695             }
6696
6697             /* r4 */
6698             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
6699             ok(hr == S_OK, "ret %08x\n", hr );
6700             if(hr == S_OK)
6701             {
6702                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6703
6704                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
6705                 ok(hr == S_OK, "ret %08x\n", hr );
6706
6707                 IXMLDOMElement_Release(pElement);
6708             }
6709
6710             /* r8 */
6711             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
6712             ok(hr == S_OK, "ret %08x\n", hr );
6713             if(hr == S_OK)
6714             {
6715                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6716
6717                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
6718                 ok(hr == S_OK, "ret %08x\n", hr );
6719
6720                 IXMLDOMElement_Release(pElement);
6721             }
6722
6723             /* float */
6724             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
6725             ok(hr == S_OK, "ret %08x\n", hr );
6726             if(hr == S_OK)
6727             {
6728                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6729
6730                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
6731                 ok(hr == S_OK, "ret %08x\n", hr );
6732
6733                 IXMLDOMElement_Release(pElement);
6734             }
6735
6736             /* uuid */
6737             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
6738             ok(hr == S_OK, "ret %08x\n", hr );
6739             if(hr == S_OK)
6740             {
6741                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6742
6743                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
6744                 ok(hr == S_OK, "ret %08x\n", hr );
6745
6746                 IXMLDOMElement_Release(pElement);
6747             }
6748
6749             /* bin.hex */
6750             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
6751             ok(hr == S_OK, "ret %08x\n", hr );
6752             if(hr == S_OK)
6753             {
6754                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6755
6756                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
6757                 ok(hr == S_OK, "ret %08x\n", hr );
6758
6759                 IXMLDOMElement_Release(pElement);
6760             }
6761
6762             /* bin.base64 */
6763             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
6764             ok(hr == S_OK, "ret %08x\n", hr );
6765             if(hr == S_OK)
6766             {
6767                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6768
6769                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
6770                 ok(hr == S_OK, "ret %08x\n", hr );
6771
6772                 IXMLDOMElement_Release(pElement);
6773             }
6774
6775             /* Check changing types */
6776             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
6777             ok(hr == S_OK, "ret %08x\n", hr );
6778             if(hr == S_OK)
6779             {
6780                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6781
6782                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6783                 ok(hr == S_OK, "ret %08x\n", hr );
6784
6785                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
6786                 ok(hr == S_OK, "ret %08x\n", hr );
6787
6788                 IXMLDOMElement_Release(pElement);
6789             }
6790
6791             IXMLDOMElement_Release(pRoot);
6792         }
6793     }
6794
6795     IXMLDOMDocument_Release(doc);
6796
6797     free_bstrs();
6798 }
6799
6800 static void test_save(void)
6801 {
6802     IXMLDOMDocument *doc, *doc2;
6803     IXMLDOMElement *root;
6804     VARIANT file, vDoc;
6805     BSTR sOrig, sNew, filename;
6806     char buffer[100];
6807     DWORD read = 0;
6808     HANDLE hfile;
6809     HRESULT hr;
6810
6811     doc = create_document(&IID_IXMLDOMDocument);
6812     if (!doc) return;
6813
6814     doc2 = create_document(&IID_IXMLDOMDocument);
6815     if (!doc2)
6816     {
6817         IXMLDOMDocument_Release(doc);
6818         return;
6819     }
6820
6821     /* save to IXMLDOMDocument */
6822     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6823     EXPECT_HR(hr, S_OK);
6824
6825     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6826     EXPECT_HR(hr, S_OK);
6827
6828     V_VT(&vDoc) = VT_UNKNOWN;
6829     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
6830
6831     hr = IXMLDOMDocument_save(doc, vDoc);
6832     EXPECT_HR(hr, S_OK);
6833
6834     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
6835     EXPECT_HR(hr, S_OK);
6836
6837     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
6838     EXPECT_HR(hr, S_OK);
6839
6840     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
6841
6842     SysFreeString(sOrig);
6843     SysFreeString(sNew);
6844
6845     IXMLDOMElement_Release(root);
6846     IXMLDOMDocument_Release(doc2);
6847
6848     /* save to path */
6849     V_VT(&file) = VT_BSTR;
6850     V_BSTR(&file) = _bstr_("test.xml");
6851
6852     hr = IXMLDOMDocument_save(doc, file);
6853     EXPECT_HR(hr, S_OK);
6854
6855     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6856     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6857     if(hfile == INVALID_HANDLE_VALUE) return;
6858
6859     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6860     ok(read != 0, "could not read file\n");
6861     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6862
6863     CloseHandle(hfile);
6864     DeleteFile("test.xml");
6865
6866     /* save to path VT_BSTR | VT_BYREF */
6867     filename = _bstr_("test.xml");
6868     V_VT(&file) = VT_BSTR | VT_BYREF;
6869     V_BSTRREF(&file) = &filename;
6870
6871     hr = IXMLDOMDocument_save(doc, file);
6872     EXPECT_HR(hr, S_OK);
6873
6874     IXMLDOMDocument_Release(doc);
6875
6876     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6877     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6878     if(hfile == INVALID_HANDLE_VALUE) return;
6879
6880     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6881     ok(read != 0, "could not read file\n");
6882     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6883
6884     CloseHandle(hfile);
6885     DeleteFile("test.xml");
6886     free_bstrs();
6887 }
6888
6889 static void test_testTransforms(void)
6890 {
6891     IXMLDOMDocument *doc, *docSS;
6892     IXMLDOMNode *pNode;
6893     VARIANT_BOOL bSucc;
6894
6895     HRESULT hr;
6896
6897     doc = create_document(&IID_IXMLDOMDocument);
6898     if (!doc) return;
6899
6900     docSS = create_document(&IID_IXMLDOMDocument);
6901     if (!docSS)
6902     {
6903         IXMLDOMDocument_Release(doc);
6904         return;
6905     }
6906
6907     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
6908     ok(hr == S_OK, "ret %08x\n", hr );
6909
6910     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
6911     ok(hr == S_OK, "ret %08x\n", hr );
6912
6913     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
6914     ok(hr == S_OK, "ret %08x\n", hr );
6915     if(hr == S_OK)
6916     {
6917         BSTR bOut;
6918
6919         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
6920         ok(hr == S_OK, "ret %08x\n", hr );
6921         if(hr == S_OK)
6922         {
6923             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
6924             SysFreeString(bOut);
6925         }
6926
6927         IXMLDOMNode_Release(pNode);
6928     }
6929
6930     IXMLDOMDocument_Release(docSS);
6931     IXMLDOMDocument_Release(doc);
6932
6933     free_bstrs();
6934 }
6935
6936 static void test_namespaces(void)
6937 {
6938     static const CHAR namespaces_xmlA[] =
6939         "<?xml version=\"1.0\"?>\n"
6940         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
6941         "  <XMI.content>"
6942         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
6943         "  </XMI.content>"
6944         "</XMI>";
6945
6946     IXMLDOMDocument *doc;
6947     IXMLDOMElement *elem;
6948     IXMLDOMNode *node;
6949
6950     VARIANT_BOOL b;
6951     VARIANT var;
6952     HRESULT hr;
6953     BSTR str;
6954
6955     doc = create_document(&IID_IXMLDOMDocument);
6956     if (!doc) return;
6957
6958     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
6959     EXPECT_HR(hr, S_OK);
6960     ok(b == VARIANT_TRUE, "got %d\n", b);
6961
6962     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
6963     EXPECT_HR(hr, S_OK);
6964     if(hr == S_OK)
6965     {
6966         IXMLDOMAttribute *attr;
6967         IXMLDOMNode *node2;
6968
6969         hr = IXMLDOMNode_get_firstChild(node, &node2);
6970         EXPECT_HR(hr, S_OK);
6971         ok(node2 != NULL, "got %p\n", node2);
6972
6973         /* Test get_prefix */
6974         hr = IXMLDOMNode_get_prefix(node2, NULL);
6975         EXPECT_HR(hr, E_INVALIDARG);
6976         /* NOTE: Need to test that arg2 gets cleared on Error. */
6977
6978         hr = IXMLDOMNode_get_prefix(node2, &str);
6979         EXPECT_HR(hr, S_OK);
6980         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
6981         SysFreeString(str);
6982
6983         hr = IXMLDOMNode_get_nodeName(node2, &str);
6984         EXPECT_HR(hr, S_OK);
6985         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
6986         SysFreeString(str);
6987
6988         /* Test get_namespaceURI */
6989         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
6990         EXPECT_HR(hr, E_INVALIDARG);
6991         /* NOTE: Need to test that arg2 gets cleared on Error. */
6992
6993         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
6994         EXPECT_HR(hr, S_OK);
6995         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
6996         SysFreeString(str);
6997
6998         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
6999         EXPECT_HR(hr, S_OK);
7000
7001         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7002         EXPECT_HR(hr, S_OK);
7003
7004         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7005         EXPECT_HR(hr, S_OK);
7006         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7007         SysFreeString(str);
7008
7009         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7010         EXPECT_HR(hr, S_OK);
7011         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7012         SysFreeString(str);
7013
7014         IXMLDOMAttribute_Release(attr);
7015         IXMLDOMElement_Release(elem);
7016
7017         IXMLDOMNode_Release(node2);
7018         IXMLDOMNode_Release(node);
7019     }
7020
7021     IXMLDOMDocument_Release(doc);
7022
7023     /* create on element and try to alter namespace after that */
7024     doc = create_document(&IID_IXMLDOMDocument);
7025     if (!doc) return;
7026
7027     V_VT(&var) = VT_I2;
7028     V_I2(&var) = NODE_ELEMENT;
7029
7030     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7031     EXPECT_HR(hr, S_OK);
7032
7033     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7034     EXPECT_HR(hr, S_OK);
7035
7036     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7037     EXPECT_HR(hr, S_OK);
7038
7039     V_VT(&var) = VT_BSTR;
7040     V_BSTR(&var) = _bstr_("ns/uri2");
7041
7042     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7043     EXPECT_HR(hr, E_INVALIDARG);
7044
7045     V_VT(&var) = VT_BSTR;
7046     V_BSTR(&var) = _bstr_("ns/uri");
7047
7048     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7049     EXPECT_HR(hr, S_OK);
7050
7051     hr = IXMLDOMElement_get_xml(elem, &str);
7052     EXPECT_HR(hr, S_OK);
7053     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7054     SysFreeString(str);
7055
7056     IXMLDOMElement_Release(elem);
7057     IXMLDOMDocument_Release(doc);
7058
7059     /* create on element and try to alter namespace after that */
7060     doc = create_document_version(60, &IID_IXMLDOMDocument);
7061     if (!doc) return;
7062
7063     V_VT(&var) = VT_I2;
7064     V_I2(&var) = NODE_ELEMENT;
7065
7066     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7067     EXPECT_HR(hr, S_OK);
7068
7069     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7070     EXPECT_HR(hr, S_OK);
7071
7072     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7073     EXPECT_HR(hr, S_OK);
7074
7075     /* try same prefix, different uri */
7076     V_VT(&var) = VT_BSTR;
7077     V_BSTR(&var) = _bstr_("ns/uri2");
7078
7079     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7080     EXPECT_HR(hr, E_INVALIDARG);
7081
7082     /* try same prefix and uri */
7083     V_VT(&var) = VT_BSTR;
7084     V_BSTR(&var) = _bstr_("ns/uri");
7085
7086     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7087     EXPECT_HR(hr, S_OK);
7088
7089     hr = IXMLDOMElement_get_xml(elem, &str);
7090     EXPECT_HR(hr, S_OK);
7091     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7092     SysFreeString(str);
7093
7094     IXMLDOMElement_Release(elem);
7095     IXMLDOMDocument_Release(doc);
7096
7097     free_bstrs();
7098 }
7099
7100 static void test_FormattingXML(void)
7101 {
7102     IXMLDOMDocument *doc;
7103     IXMLDOMElement *pElement;
7104     VARIANT_BOOL bSucc;
7105     HRESULT hr;
7106     BSTR str;
7107     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7108     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7109
7110     doc = create_document(&IID_IXMLDOMDocument);
7111     if (!doc) return;
7112
7113     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7114     ok(hr == S_OK, "ret %08x\n", hr );
7115     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7116
7117     if(bSucc == VARIANT_TRUE)
7118     {
7119         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7120         ok(hr == S_OK, "ret %08x\n", hr );
7121         if(hr == S_OK)
7122         {
7123             hr = IXMLDOMElement_get_xml(pElement, &str);
7124             ok(hr == S_OK, "ret %08x\n", hr );
7125             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7126             SysFreeString(str);
7127
7128             IXMLDOMElement_Release(pElement);
7129         }
7130     }
7131
7132     IXMLDOMDocument_Release(doc);
7133
7134     free_bstrs();
7135 }
7136
7137 typedef struct _nodetypedvalue_t {
7138     const char *name;
7139     VARTYPE type;
7140     const char *value; /* value in string format */
7141 } nodetypedvalue_t;
7142
7143 static const nodetypedvalue_t get_nodetypedvalue[] = {
7144     { "root/string",    VT_BSTR, "Wine" },
7145     { "root/string2",   VT_BSTR, "String" },
7146     { "root/number",    VT_BSTR, "12.44" },
7147     { "root/number2",   VT_BSTR, "-3.71e3" },
7148     { "root/int",       VT_I4,   "-13" },
7149     { "root/fixed",     VT_CY,   "7322.9371" },
7150     { "root/bool",      VT_BOOL, "-1" },
7151     { "root/datetime",  VT_DATE, "40135.14" },
7152     { "root/datetimetz",VT_DATE, "37813.59" },
7153     { "root/date",      VT_DATE, "665413" },
7154     { "root/time",      VT_DATE, "0.5813889" },
7155     { "root/timetz",    VT_DATE, "1.112512" },
7156     { "root/i1",        VT_I1,   "-13" },
7157     { "root/i2",        VT_I2,   "31915" },
7158     { "root/i4",        VT_I4,   "-312232" },
7159     { "root/ui1",       VT_UI1,  "123" },
7160     { "root/ui2",       VT_UI2,  "48282" },
7161     { "root/ui4",       VT_UI4,  "949281" },
7162     { "root/r4",        VT_R4,   "213124" },
7163     { "root/r8",        VT_R8,   "0.412" },
7164     { "root/float",     VT_R8,   "41221.421" },
7165     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7166     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7167     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7168     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7169     { 0 }
7170 };
7171
7172 static void test_nodeTypedValue(void)
7173 {
7174     const nodetypedvalue_t *entry = get_nodetypedvalue;
7175     IXMLDOMDocumentType *doctype, *doctype2;
7176     IXMLDOMProcessingInstruction *pi;
7177     IXMLDOMDocumentFragment *frag;
7178     IXMLDOMDocument *doc, *doc2;
7179     IXMLDOMCDATASection *cdata;
7180     IXMLDOMComment *comment;
7181     IXMLDOMNode *node;
7182     VARIANT_BOOL b;
7183     VARIANT value;
7184     HRESULT hr;
7185
7186     doc = create_document(&IID_IXMLDOMDocument);
7187     if (!doc) return;
7188
7189     b = VARIANT_FALSE;
7190     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7191     ok(hr == S_OK, "ret %08x\n", hr );
7192     ok(b == VARIANT_TRUE, "got %d\n", b);
7193
7194     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7195     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7196
7197     V_VT(&value) = VT_BSTR;
7198     V_BSTR(&value) = NULL;
7199     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7200     ok(hr == S_FALSE, "ret %08x\n", hr );
7201     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7202
7203     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7204     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7205
7206     V_VT(&value) = VT_EMPTY;
7207     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7208     ok(hr == S_FALSE, "ret %08x\n", hr );
7209     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7210
7211     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7212     ok(hr == S_OK, "ret %08x\n", hr );
7213
7214     V_VT(&value) = VT_BSTR;
7215     V_BSTR(&value) = NULL;
7216     hr = IXMLDOMNode_get_nodeValue(node, &value);
7217     ok(hr == S_FALSE, "ret %08x\n", hr );
7218     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7219
7220     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7221     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7222
7223     IXMLDOMNode_Release(node);
7224
7225     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7226     ok(hr == S_OK, "ret %08x\n", hr );
7227     {
7228         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7229
7230         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7231         ok(hr == S_OK, "ret %08x\n", hr );
7232         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7233         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7234         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7235             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7236         VariantClear(&value);
7237         IXMLDOMNode_Release(node);
7238     }
7239
7240     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7241     ok(hr == S_OK, "ret %08x\n", hr );
7242     {
7243         V_VT(&value) = VT_NULL;
7244         V_BSTR(&value) = (void*)0xdeadbeef;
7245         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7246         ok(hr == S_OK, "ret %08x\n", hr );
7247         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7248         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7249         IXMLDOMProcessingInstruction_Release(pi);
7250         VariantClear(&value);
7251     }
7252
7253     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7254     ok(hr == S_OK, "ret %08x\n", hr );
7255     {
7256         V_VT(&value) = VT_NULL;
7257         V_BSTR(&value) = (void*)0xdeadbeef;
7258         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7259         ok(hr == S_OK, "ret %08x\n", hr );
7260         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7261         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7262         IXMLDOMCDATASection_Release(cdata);
7263         VariantClear(&value);
7264     }
7265
7266     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7267     ok(hr == S_OK, "ret %08x\n", hr );
7268     {
7269         V_VT(&value) = VT_NULL;
7270         V_BSTR(&value) = (void*)0xdeadbeef;
7271         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7272         ok(hr == S_OK, "ret %08x\n", hr );
7273         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7274         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7275         IXMLDOMComment_Release(comment);
7276         VariantClear(&value);
7277     }
7278
7279     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7280     ok(hr == S_OK, "ret %08x\n", hr );
7281     {
7282         V_VT(&value) = VT_EMPTY;
7283         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7284         ok(hr == S_FALSE, "ret %08x\n", hr );
7285         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7286         IXMLDOMDocumentFragment_Release(frag);
7287     }
7288
7289     doc2 = create_document(&IID_IXMLDOMDocument);
7290
7291     b = VARIANT_FALSE;
7292     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7293     ok(hr == S_OK, "ret %08x\n", hr );
7294     ok(b == VARIANT_TRUE, "got %d\n", b);
7295
7296     EXPECT_REF(doc2, 1);
7297
7298     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7299     ok(hr == S_OK, "ret %08x\n", hr );
7300
7301     EXPECT_REF(doc2, 1);
7302     todo_wine EXPECT_REF(doctype, 2);
7303
7304     {
7305         V_VT(&value) = VT_EMPTY;
7306         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7307         ok(hr == S_FALSE, "ret %08x\n", hr );
7308         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7309     }
7310
7311     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7312     ok(hr == S_OK, "ret %08x\n", hr );
7313     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7314
7315     IXMLDOMDocumentType_Release(doctype2);
7316     IXMLDOMDocumentType_Release(doctype);
7317
7318     IXMLDOMDocument_Release(doc2);
7319
7320     while (entry->name)
7321     {
7322         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7323         ok(hr == S_OK, "ret %08x\n", hr );
7324
7325         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7326         ok(hr == S_OK, "ret %08x\n", hr );
7327         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7328
7329         if (entry->type == (VT_ARRAY|VT_UI1))
7330         {
7331             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7332                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7333         }
7334
7335         if (entry->type != VT_BSTR)
7336         {
7337            if (entry->type == VT_DATE ||
7338                entry->type == VT_R8 ||
7339                entry->type == VT_CY)
7340            {
7341                if (entry->type == VT_DATE)
7342                {
7343                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7344                    ok(hr == S_OK, "ret %08x\n", hr );
7345                }
7346                hr = VariantChangeTypeEx(&value, &value,
7347                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7348                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7349                ok(hr == S_OK, "ret %08x\n", hr );
7350            }
7351            else
7352            {
7353                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7354                ok(hr == S_OK, "ret %08x\n", hr );
7355            }
7356
7357            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7358            if (entry->type == (VT_ARRAY|VT_UI1))
7359            {
7360                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7361                   "expected %s\n", entry->value);
7362            }
7363            else
7364                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7365                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7366         }
7367         else
7368            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7369                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7370
7371         VariantClear( &value );
7372         IXMLDOMNode_Release(node);
7373
7374         entry++;
7375     }
7376
7377     IXMLDOMDocument_Release(doc);
7378     free_bstrs();
7379 }
7380
7381 static void test_TransformWithLoadingLocalFile(void)
7382 {
7383     IXMLDOMDocument *doc;
7384     IXMLDOMDocument *xsl;
7385     IXMLDOMNode *pNode;
7386     VARIANT_BOOL bSucc;
7387     HRESULT hr;
7388     HANDLE file;
7389     DWORD dwWritten;
7390     char lpPathBuffer[MAX_PATH];
7391     int i;
7392
7393     /* Create a Temp File. */
7394     GetTempPathA(MAX_PATH, lpPathBuffer);
7395     strcat(lpPathBuffer, "customers.xml" );
7396
7397     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7398     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7399     if(file == INVALID_HANDLE_VALUE)
7400         return;
7401
7402     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7403     CloseHandle(file);
7404
7405     /* Correct path to not include a escape character. */
7406     for(i=0; i < strlen(lpPathBuffer); i++)
7407     {
7408         if(lpPathBuffer[i] == '\\')
7409             lpPathBuffer[i] = '/';
7410     }
7411
7412     doc = create_document(&IID_IXMLDOMDocument);
7413     if (!doc) return;
7414
7415     xsl = create_document(&IID_IXMLDOMDocument);
7416     if (!xsl)
7417     {
7418         IXMLDOMDocument2_Release(doc);
7419         return;
7420     }
7421
7422     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7423     ok(hr == S_OK, "ret %08x\n", hr );
7424     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7425     if(bSucc == VARIANT_TRUE)
7426     {
7427         BSTR sXSL;
7428         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7429         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7430         BSTR sFileName = _bstr_(lpPathBuffer);
7431         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7432
7433         sXSL = SysAllocStringLen(NULL, nLegnth);
7434         lstrcpyW(sXSL, sPart1);
7435         lstrcatW(sXSL, sFileName);
7436         lstrcatW(sXSL, sPart2);
7437
7438         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7439         ok(hr == S_OK, "ret %08x\n", hr );
7440         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7441         if(bSucc == VARIANT_TRUE)
7442         {
7443             BSTR sResult;
7444
7445             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7446             ok(hr == S_OK, "ret %08x\n", hr );
7447             if(hr == S_OK)
7448             {
7449                 /* This will load the temp file via the XSL */
7450                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7451                 ok(hr == S_OK, "ret %08x\n", hr );
7452                 if(hr == S_OK)
7453                 {
7454                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7455                     SysFreeString(sResult);
7456                 }
7457
7458                 IXMLDOMNode_Release(pNode);
7459             }
7460         }
7461
7462         SysFreeString(sXSL);
7463     }
7464
7465     IXMLDOMDocument_Release(doc);
7466     IXMLDOMDocument_Release(xsl);
7467
7468     DeleteFile(lpPathBuffer);
7469     free_bstrs();
7470 }
7471
7472 static void test_put_nodeValue(void)
7473 {
7474     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7475     IXMLDOMDocument *doc;
7476     IXMLDOMText *text;
7477     IXMLDOMEntityReference *entityref;
7478     IXMLDOMAttribute *attr;
7479     IXMLDOMNode *node;
7480     HRESULT hr;
7481     VARIANT data, type;
7482
7483     doc = create_document(&IID_IXMLDOMDocument);
7484     if (!doc) return;
7485
7486     /* test for unsupported types */
7487     /* NODE_DOCUMENT */
7488     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7489     ok(hr == S_OK, "ret %08x\n", hr );
7490     V_VT(&data) = VT_BSTR;
7491     V_BSTR(&data) = _bstr_("one two three");
7492     hr = IXMLDOMNode_put_nodeValue(node, data);
7493     ok(hr == E_FAIL, "ret %08x\n", hr );
7494     IXMLDOMNode_Release(node);
7495
7496     /* NODE_DOCUMENT_FRAGMENT */
7497     V_VT(&type) = VT_I1;
7498     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7499     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7500     ok(hr == S_OK, "ret %08x\n", hr );
7501     V_VT(&data) = VT_BSTR;
7502     V_BSTR(&data) = _bstr_("one two three");
7503     hr = IXMLDOMNode_put_nodeValue(node, data);
7504     ok(hr == E_FAIL, "ret %08x\n", hr );
7505     IXMLDOMNode_Release(node);
7506
7507     /* NODE_ELEMENT */
7508     V_VT(&type) = VT_I1;
7509     V_I1(&type) = NODE_ELEMENT;
7510     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7511     ok(hr == S_OK, "ret %08x\n", hr );
7512     V_VT(&data) = VT_BSTR;
7513     V_BSTR(&data) = _bstr_("one two three");
7514     hr = IXMLDOMNode_put_nodeValue(node, data);
7515     ok(hr == E_FAIL, "ret %08x\n", hr );
7516     IXMLDOMNode_Release(node);
7517
7518     /* NODE_ENTITY_REFERENCE */
7519     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7520     ok(hr == S_OK, "ret %08x\n", hr );
7521
7522     V_VT(&data) = VT_BSTR;
7523     V_BSTR(&data) = _bstr_("one two three");
7524     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7525     ok(hr == E_FAIL, "ret %08x\n", hr );
7526
7527     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7528     ok(hr == S_OK, "ret %08x\n", hr );
7529     V_VT(&data) = VT_BSTR;
7530     V_BSTR(&data) = _bstr_("one two three");
7531     hr = IXMLDOMNode_put_nodeValue(node, data);
7532     ok(hr == E_FAIL, "ret %08x\n", hr );
7533     IXMLDOMNode_Release(node);
7534     IXMLDOMEntityReference_Release(entityref);
7535
7536     /* supported types */
7537     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7538     ok(hr == S_OK, "ret %08x\n", hr );
7539     V_VT(&data) = VT_BSTR;
7540     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7541     hr = IXMLDOMText_put_nodeValue(text, data);
7542     ok(hr == S_OK, "ret %08x\n", hr );
7543     IXMLDOMText_Release(text);
7544
7545     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7546     ok(hr == S_OK, "ret %08x\n", hr );
7547     V_VT(&data) = VT_BSTR;
7548     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7549     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7550     ok(hr == S_OK, "ret %08x\n", hr );
7551     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7552     ok(hr == S_OK, "ret %08x\n", hr );
7553     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7554         wine_dbgstr_w(V_BSTR(&data)));
7555     VariantClear(&data);
7556     IXMLDOMAttribute_Release(attr);
7557
7558     free_bstrs();
7559
7560     IXMLDOMDocument_Release(doc);
7561 }
7562
7563 static void test_document_IObjectSafety(void)
7564 {
7565     IXMLDOMDocument *doc;
7566     IObjectSafety *safety;
7567     HRESULT hr;
7568
7569     doc = create_document(&IID_IXMLDOMDocument);
7570     if (!doc) return;
7571
7572     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7573     ok(hr == S_OK, "ret %08x\n", hr );
7574
7575     test_IObjectSafety_common(safety);
7576
7577     IObjectSafety_Release(safety);
7578
7579     IXMLDOMDocument_Release(doc);
7580 }
7581
7582 typedef struct _property_test_t {
7583     const GUID *guid;
7584     const char *clsid;
7585     const char *property;
7586     const char *value;
7587 } property_test_t;
7588
7589 static const property_test_t properties_test_data[] = {
7590     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7591     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7592     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7593     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7594     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7595     { 0 }
7596 };
7597
7598 static void test_default_properties(void)
7599 {
7600     const property_test_t *entry = properties_test_data;
7601
7602     while (entry->guid)
7603     {
7604         IXMLDOMDocument2 *doc;
7605         VARIANT var;
7606         HRESULT hr;
7607
7608         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7609         if (hr != S_OK)
7610         {
7611             win_skip("can't create %s instance\n", entry->clsid);
7612             entry++;
7613             continue;
7614         }
7615
7616         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7617         ok(hr == S_OK, "got 0x%08x\n", hr);
7618         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7619            entry->value, entry->clsid);
7620         VariantClear(&var);
7621
7622         IXMLDOMDocument2_Release(doc);
7623
7624         entry++;
7625     }
7626 }
7627
7628 typedef struct {
7629     const char *query;
7630     const char *list;
7631 } xslpattern_test_t;
7632
7633 static const xslpattern_test_t xslpattern_test[] = {
7634     { "root//elem[0]", "E1.E2.D1" },
7635     { "root//elem[index()=1]", "E2.E2.D1" },
7636     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7637     { "root//elem[end()]", "E4.E2.D1" },
7638     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7639     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7640     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7641     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7642     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7643     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7644     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7645     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7646     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7647     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7648     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7649     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7650     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7651     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7652     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7653     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7654     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7655     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7656     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7657     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7658     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7659     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7660     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7661     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7662     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7663     { NULL }
7664 };
7665
7666 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7667     /* prefixes don't need to be registered, you may use them as they are in the doc */
7668     { "//bar:x", "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1" },
7669     /* prefixes must be explicitly specified in the name */
7670     { "//foo:elem", "" },
7671     { "//foo:c", "E3.E4.E2.D1" },
7672     { NULL }
7673 };
7674
7675 static const xslpattern_test_t xslpattern_test_func[] = {
7676     { "attribute()", "" },
7677     { "attribute('depth')", "" },
7678     { "root/attribute('depth')", "A'depth'.E3.D1" },
7679     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7680     { "//x//attribute(id)", NULL },
7681     { "//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" },
7682     { "comment()", "C2.D1" },
7683     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7684     { "element()", "E3.D1" },
7685     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7686     { "//element(a)", NULL },
7687     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7688     { "node()", "P1.D1 C2.D1 E3.D1" },
7689     { "//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" },
7690     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7691     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7692     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7693     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7694     { "pi()", "P1.D1" },
7695     { "//y/pi()", "P1.E4.E3.D1" },
7696     { "root/textnode()", "T2.E3.D1" },
7697     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7698     { NULL }
7699 };
7700
7701 static void test_XSLPattern(void)
7702 {
7703     const xslpattern_test_t *ptr = xslpattern_test;
7704     IXMLDOMDocument2 *doc;
7705     IXMLDOMNodeList *list;
7706     VARIANT_BOOL b;
7707     HRESULT hr;
7708     LONG len;
7709
7710     doc = create_document(&IID_IXMLDOMDocument2);
7711     if (!doc) return;
7712
7713     b = VARIANT_FALSE;
7714     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7715     EXPECT_HR(hr, S_OK);
7716     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7717
7718     /* switch to XSLPattern */
7719     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7720     EXPECT_HR(hr, S_OK);
7721
7722     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7723     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7724     EXPECT_HR(hr, S_OK);
7725
7726     len = 0;
7727     hr = IXMLDOMNodeList_get_length(list, &len);
7728     EXPECT_HR(hr, S_OK);
7729     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7730     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7731     IXMLDOMNodeList_Release(list);
7732
7733     while (ptr->query)
7734     {
7735         list = NULL;
7736         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7737         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7738         len = 0;
7739         hr = IXMLDOMNodeList_get_length(list, &len);
7740         ok(len != 0, "query=%s, empty list\n", ptr->query);
7741         if (len)
7742             expect_list_and_release(list, ptr->list);
7743
7744         ptr++;
7745     }
7746
7747     /* namespace handling */
7748     /* no registered namespaces */
7749     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7750     EXPECT_HR(hr, S_OK);
7751
7752     ptr = xslpattern_test_no_ns;
7753     while (ptr->query)
7754     {
7755         list = NULL;
7756         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7757         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7758
7759         if (*ptr->list)
7760         {
7761             len = 0;
7762             hr = IXMLDOMNodeList_get_length(list, &len);
7763             EXPECT_HR(hr, S_OK);
7764             ok(len != 0, "query=%s, empty list\n", ptr->query);
7765         }
7766         else
7767         {
7768             len = 1;
7769             hr = IXMLDOMNodeList_get_length(list, &len);
7770             EXPECT_HR(hr, S_OK);
7771             ok(len == 0, "query=%s, empty list\n", ptr->query);
7772         }
7773         if (len)
7774             expect_list_and_release(list, ptr->list);
7775
7776         ptr++;
7777     }
7778
7779     /* explicitly register prefix foo */
7780     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7781
7782     /* now we get the same behavior as XPath */
7783     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7784     EXPECT_HR(hr, S_OK);
7785     len = 0;
7786     hr = IXMLDOMNodeList_get_length(list, &len);
7787     EXPECT_HR(hr, S_OK);
7788     ok(len != 0, "expected filled list\n");
7789     if (len)
7790         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
7791
7792     /* set prefix foo to some nonexistent namespace */
7793     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
7794     EXPECT_HR(hr, S_OK);
7795
7796     /* the registered prefix takes precedence */
7797     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7798     EXPECT_HR(hr, S_OK);
7799     len = 0;
7800     hr = IXMLDOMNodeList_get_length(list, &len);
7801     EXPECT_HR(hr, S_OK);
7802     ok(len == 0, "expected empty list\n");
7803     IXMLDOMNodeList_Release(list);
7804
7805     IXMLDOMDocument2_Release(doc);
7806
7807     doc = create_document(&IID_IXMLDOMDocument2);
7808     if (!doc) return;
7809
7810     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
7811     EXPECT_HR(hr, S_OK);
7812     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7813
7814     ptr = xslpattern_test_func;
7815     while (ptr->query)
7816     {
7817         list = NULL;
7818         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7819         if (ptr->list)
7820         {
7821             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7822             len = 0;
7823             hr = IXMLDOMNodeList_get_length(list, &len);
7824             if (*ptr->list)
7825             {
7826                 ok(len != 0, "query=%s, empty list\n", ptr->query);
7827                 if (len)
7828                     expect_list_and_release(list, ptr->list);
7829             }
7830             else
7831                 ok(len == 0, "query=%s, filled list\n", ptr->query);
7832         }
7833         else
7834             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7835
7836         ptr++;
7837     }
7838
7839     IXMLDOMDocument2_Release(doc);
7840     free_bstrs();
7841 }
7842
7843 static void test_splitText(void)
7844 {
7845     IXMLDOMCDATASection *cdata;
7846     IXMLDOMElement *root;
7847     IXMLDOMDocument *doc;
7848     IXMLDOMText *text, *text2;
7849     IXMLDOMNode *node;
7850     VARIANT var;
7851     VARIANT_BOOL success;
7852     LONG length;
7853     HRESULT hr;
7854
7855     doc = create_document(&IID_IXMLDOMDocument);
7856     if (!doc) return;
7857
7858     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
7859     ok(hr == S_OK, "got 0x%08x\n", hr);
7860
7861     hr = IXMLDOMDocument_get_documentElement(doc, &root);
7862     ok(hr == S_OK, "got 0x%08x\n", hr);
7863
7864     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
7865     ok(hr == S_OK, "got 0x%08x\n", hr);
7866
7867     V_VT(&var) = VT_EMPTY;
7868     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
7869     ok(hr == S_OK, "got 0x%08x\n", hr);
7870
7871     length = 0;
7872     hr = IXMLDOMCDATASection_get_length(cdata, &length);
7873     ok(hr == S_OK, "got 0x%08x\n", hr);
7874     ok(length > 0, "got %d\n", length);
7875
7876     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
7877     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7878
7879     text = (void*)0xdeadbeef;
7880     /* negative offset */
7881     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
7882     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7883     ok(text == (void*)0xdeadbeef, "got %p\n", text);
7884
7885     text = (void*)0xdeadbeef;
7886     /* offset outside data */
7887     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
7888     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7889     ok(text == 0, "got %p\n", text);
7890
7891     text = (void*)0xdeadbeef;
7892     /* offset outside data */
7893     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
7894     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7895     ok(text == 0, "got %p\n", text);
7896
7897     /* no empty node created */
7898     node = (void*)0xdeadbeef;
7899     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7900     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7901     ok(node == 0, "got %p\n", text);
7902
7903     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
7904     ok(hr == S_OK, "got 0x%08x\n", hr);
7905
7906     length = 0;
7907     hr = IXMLDOMText_get_length(text, &length);
7908     ok(hr == S_OK, "got 0x%08x\n", hr);
7909     ok(length == 7, "got %d\n", length);
7910
7911     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7912     ok(hr == S_OK, "got 0x%08x\n", hr);
7913     IXMLDOMNode_Release(node);
7914
7915     /* split new text node */
7916     hr = IXMLDOMText_get_length(text, &length);
7917     ok(hr == S_OK, "got 0x%08x\n", hr);
7918
7919     node = (void*)0xdeadbeef;
7920     hr = IXMLDOMText_get_nextSibling(text, &node);
7921     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7922     ok(node == 0, "got %p\n", text);
7923
7924     hr = IXMLDOMText_splitText(text, 0, NULL);
7925     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7926
7927     text2 = (void*)0xdeadbeef;
7928     /* negative offset */
7929     hr = IXMLDOMText_splitText(text, -1, &text2);
7930     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7931     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
7932
7933     text2 = (void*)0xdeadbeef;
7934     /* offset outside data */
7935     hr = IXMLDOMText_splitText(text, length + 1, &text2);
7936     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7937     ok(text2 == 0, "got %p\n", text2);
7938
7939     text2 = (void*)0xdeadbeef;
7940     /* offset outside data */
7941     hr = IXMLDOMText_splitText(text, length, &text2);
7942     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7943     ok(text2 == 0, "got %p\n", text);
7944
7945     text2 = 0;
7946     hr = IXMLDOMText_splitText(text, 4, &text2);
7947     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7948     if (text2) IXMLDOMText_Release(text2);
7949
7950     node = 0;
7951     hr = IXMLDOMText_get_nextSibling(text, &node);
7952     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7953     if (node) IXMLDOMNode_Release(node);
7954
7955     IXMLDOMText_Release(text);
7956     IXMLDOMElement_Release(root);
7957     IXMLDOMCDATASection_Release(cdata);
7958     free_bstrs();
7959 }
7960
7961 typedef struct {
7962     const char *name;
7963     const char *uri;
7964     HRESULT hr;
7965 } ns_item_t;
7966
7967 /* default_ns_doc used */
7968 static const ns_item_t qualified_item_tests[] = {
7969     { "xml:lang", NULL, S_FALSE },
7970     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
7971     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
7972     { "ns:b", NULL, S_FALSE },
7973     { "ns:b", "nshref", S_FALSE },
7974     { "b", "nshref", S_OK },
7975     { "d", NULL, S_OK },
7976     { NULL }
7977 };
7978
7979 static const ns_item_t named_item_tests[] = {
7980     { "xml:lang", NULL, S_OK },
7981     { "lang", NULL, S_FALSE },
7982     { "ns:b", NULL, S_OK },
7983     { "b", NULL, S_FALSE },
7984     { "d", NULL, S_OK },
7985     { NULL }
7986 };
7987
7988 static void test_getQualifiedItem(void)
7989 {
7990     IXMLDOMNode *pr_node, *node;
7991     IXMLDOMNodeList *root_list;
7992     IXMLDOMNamedNodeMap *map;
7993     IXMLDOMElement *element;
7994     const ns_item_t* ptr;
7995     IXMLDOMDocument *doc;
7996     VARIANT_BOOL b;
7997     HRESULT hr;
7998     LONG len;
7999
8000     doc = create_document(&IID_IXMLDOMDocument);
8001     if (!doc) return;
8002
8003     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8004     EXPECT_HR(hr, S_OK);
8005     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8006
8007     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8008     EXPECT_HR(hr, S_OK);
8009
8010     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8011     EXPECT_HR(hr, S_OK);
8012
8013     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8014     EXPECT_HR(hr, S_OK);
8015     IXMLDOMNodeList_Release(root_list);
8016
8017     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8018     EXPECT_HR(hr, S_OK);
8019     IXMLDOMNode_Release(pr_node);
8020
8021     len = 0;
8022     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8023     EXPECT_HR(hr, S_OK);
8024     ok( len == 3, "length %d\n", len);
8025
8026     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8027     EXPECT_HR(hr, E_INVALIDARG);
8028
8029     node = (void*)0xdeadbeef;
8030     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8031     EXPECT_HR(hr, E_INVALIDARG);
8032     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8033
8034     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8035     EXPECT_HR(hr, E_INVALIDARG);
8036
8037     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8038     EXPECT_HR(hr, S_OK);
8039
8040     IXMLDOMNode_Release(node);
8041     IXMLDOMNamedNodeMap_Release(map);
8042     IXMLDOMElement_Release(element);
8043
8044     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8045     EXPECT_HR(hr, S_OK);
8046
8047     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8048     EXPECT_HR(hr, S_OK);
8049
8050     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8051     EXPECT_HR(hr, S_OK);
8052     IXMLDOMNode_Release(node);
8053
8054     hr = IXMLDOMElement_get_attributes(element, &map);
8055     EXPECT_HR(hr, S_OK);
8056
8057     ptr = qualified_item_tests;
8058     while (ptr->name)
8059     {
8060        node = (void*)0xdeadbeef;
8061        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8062        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8063        if (hr == S_OK)
8064            IXMLDOMNode_Release(node);
8065        else
8066            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8067        ptr++;
8068     }
8069
8070     ptr = named_item_tests;
8071     while (ptr->name)
8072     {
8073        node = (void*)0xdeadbeef;
8074        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8075        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8076        if (hr == S_OK)
8077            IXMLDOMNode_Release(node);
8078        else
8079            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8080        ptr++;
8081     }
8082
8083     IXMLDOMNamedNodeMap_Release(map);
8084
8085     IXMLDOMElement_Release(element);
8086     IXMLDOMDocument_Release(doc);
8087     free_bstrs();
8088 }
8089
8090 static void test_removeQualifiedItem(void)
8091 {
8092     IXMLDOMDocument *doc;
8093     IXMLDOMElement *element;
8094     IXMLDOMNode *pr_node, *node;
8095     IXMLDOMNodeList *root_list;
8096     IXMLDOMNamedNodeMap *map;
8097     VARIANT_BOOL b;
8098     LONG len;
8099     HRESULT hr;
8100
8101     doc = create_document(&IID_IXMLDOMDocument);
8102     if (!doc) return;
8103
8104     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8105     ok( hr == S_OK, "loadXML failed\n");
8106     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8107
8108     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8109     ok( hr == S_OK, "ret %08x\n", hr);
8110
8111     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8112     ok( hr == S_OK, "ret %08x\n", hr);
8113
8114     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8115     ok( hr == S_OK, "ret %08x\n", hr);
8116     IXMLDOMNodeList_Release(root_list);
8117
8118     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8119     ok( hr == S_OK, "ret %08x\n", hr);
8120     IXMLDOMNode_Release(pr_node);
8121
8122     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8123     ok( hr == S_OK, "ret %08x\n", hr);
8124     ok( len == 3, "length %d\n", len);
8125
8126     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8127     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8128
8129     node = (void*)0xdeadbeef;
8130     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8131     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8132     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8133
8134     /* out pointer is optional */
8135     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8136     ok( hr == S_OK, "ret %08x\n", hr);
8137
8138     /* already removed */
8139     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8140     ok( hr == S_FALSE, "ret %08x\n", hr);
8141
8142     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8143     ok( hr == S_OK, "ret %08x\n", hr);
8144     IXMLDOMNode_Release(node);
8145
8146     IXMLDOMNamedNodeMap_Release( map );
8147     IXMLDOMElement_Release( element );
8148     IXMLDOMDocument_Release( doc );
8149     free_bstrs();
8150 }
8151
8152 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8153 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8154 {
8155     VARIANT_BOOL b;
8156     VARIANT var;
8157     HRESULT hr;
8158
8159     VariantInit(&var);
8160     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8161     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8162     VariantClear(&var);
8163
8164     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8165     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8166     VariantClear(&var);
8167
8168     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8169     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8170
8171     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8172     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8173     VariantClear(&var);
8174 }
8175
8176 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8177 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8178 {
8179     VARIANT_BOOL b;
8180     VARIANT var;
8181
8182     VariantInit(&var);
8183     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8184     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8185     VariantClear(&var);
8186
8187     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8188     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8189     VariantClear(&var);
8190
8191     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8192     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8193
8194     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8195     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8196     VariantClear(&var);
8197 }
8198
8199 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8200 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8201 {
8202     VARIANT var;
8203
8204     VariantInit(&var);
8205     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8206     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8207     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8208     V_VT(&var) = VT_DISPATCH;
8209     V_DISPATCH(&var) = NULL;
8210     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8211     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8212     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8213     VariantClear(&var);
8214 }
8215
8216 #define unset_props(doc) _unset_props(__LINE__, doc)
8217 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8218 {
8219     VARIANT var;
8220
8221     VariantInit(&var);
8222     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8223     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8224     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8225     V_VT(&var) = VT_NULL;
8226     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8227     VariantClear(&var);
8228 }
8229
8230 static void test_get_ownerDocument(void)
8231 {
8232     IXMLDOMDocument *doc1, *doc2, *doc3;
8233     IXMLDOMDocument2 *doc, *doc_owner;
8234     IXMLDOMNode *node;
8235     IXMLDOMSchemaCollection *cache;
8236     VARIANT_BOOL b;
8237     VARIANT var;
8238
8239     doc = create_document(&IID_IXMLDOMDocument2);
8240     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8241     if (!doc || !cache)
8242     {
8243         if (doc) IXMLDOMDocument2_Release(doc);
8244         if (cache) IXMLDOMSchemaCollection_Release(cache);
8245         return;
8246     }
8247
8248     VariantInit(&var);
8249
8250     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8251     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8252
8253     check_default_props(doc);
8254
8255     /* set properties and check that new instances use them */
8256     set_props(doc, cache);
8257     check_set_props(doc);
8258
8259     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8260     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8261
8262     /* new interface keeps props */
8263     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8264     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8265     check_set_props(doc_owner);
8266     IXMLDOMDocument2_Release(doc_owner);
8267
8268     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8269     IXMLDOMNode_Release(node);
8270
8271     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8272
8273     /* reload */
8274     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8275     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8276
8277     /* properties retained even after reload */
8278     check_set_props(doc);
8279
8280     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8281     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8282     IXMLDOMNode_Release(node);
8283
8284     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8285     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8286     check_set_props(doc_owner);
8287
8288     /* changing properties for one instance changes them for all */
8289     unset_props(doc_owner);
8290     check_default_props(doc_owner);
8291     check_default_props(doc);
8292
8293     IXMLDOMSchemaCollection_Release(cache);
8294     IXMLDOMDocument_Release(doc1);
8295     IXMLDOMDocument_Release(doc2);
8296     IXMLDOMDocument_Release(doc3);
8297     IXMLDOMDocument2_Release(doc);
8298     IXMLDOMDocument2_Release(doc_owner);
8299     free_bstrs();
8300 }
8301
8302 static void test_setAttributeNode(void)
8303 {
8304     IXMLDOMDocument *doc, *doc2;
8305     IXMLDOMElement *elem, *elem2;
8306     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8307     VARIANT_BOOL b;
8308     HRESULT hr;
8309     VARIANT v;
8310     BSTR str;
8311     ULONG ref1, ref2;
8312
8313     doc = create_document(&IID_IXMLDOMDocument);
8314     if (!doc) return;
8315
8316     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8317     ok( hr == S_OK, "loadXML failed\n");
8318     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8319
8320     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8321     ok( hr == S_OK, "got 0x%08x\n", hr);
8322
8323     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8324     ok( hr == S_OK, "got 0x%08x\n", hr);
8325     ok( elem2 != elem, "got same instance\n");
8326
8327     ret_attr = (void*)0xdeadbeef;
8328     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8329     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8330     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8331
8332     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8333     ok( hr == S_OK, "got 0x%08x\n", hr);
8334
8335     ref1 = IXMLDOMElement_AddRef(elem);
8336     IXMLDOMElement_Release(elem);
8337
8338     ret_attr = (void*)0xdeadbeef;
8339     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8340     ok( hr == S_OK, "got 0x%08x\n", hr);
8341     ok( ret_attr == NULL, "got %p\n", ret_attr);
8342
8343     /* no reference added */
8344     ref2 = IXMLDOMElement_AddRef(elem);
8345     IXMLDOMElement_Release(elem);
8346     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8347
8348     EXPECT_CHILDREN(elem);
8349     EXPECT_CHILDREN(elem2);
8350
8351     IXMLDOMElement_Release(elem2);
8352
8353     attr2 = NULL;
8354     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8355     ok( hr == S_OK, "got 0x%08x\n", hr);
8356     ok( attr2 != attr, "got same instance %p\n", attr2);
8357     IXMLDOMAttribute_Release(attr2);
8358
8359     /* try to add it another time */
8360     ret_attr = (void*)0xdeadbeef;
8361     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8362     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8363     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8364
8365     IXMLDOMElement_Release(elem);
8366
8367     /* initially used element is released, attribute still 'has' a container */
8368     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8369     ok( hr == S_OK, "got 0x%08x\n", hr);
8370     ret_attr = (void*)0xdeadbeef;
8371     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8372     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8373     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8374     IXMLDOMElement_Release(elem);
8375
8376     /* add attribute already attached to another document */
8377     doc2 = create_document(&IID_IXMLDOMDocument);
8378
8379     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8380     ok( hr == S_OK, "loadXML failed\n");
8381     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8382
8383     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8384     ok( hr == S_OK, "got 0x%08x\n", hr);
8385     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8386     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8387     IXMLDOMElement_Release(elem);
8388
8389     IXMLDOMAttribute_Release(attr);
8390
8391     /* create element, add attribute, see if it's copied or linked */
8392     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8393     ok( hr == S_OK, "got 0x%08x\n", hr);
8394
8395     attr = NULL;
8396     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8397     ok(hr == S_OK, "got 0x%08x\n", hr);
8398     ok(attr != NULL, "got %p\n", attr);
8399
8400     ref1 = IXMLDOMAttribute_AddRef(attr);
8401     IXMLDOMAttribute_Release(attr);
8402
8403     V_VT(&v) = VT_BSTR;
8404     V_BSTR(&v) = _bstr_("attrvalue1");
8405     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8406     ok( hr == S_OK, "got 0x%08x\n", hr);
8407
8408     str = NULL;
8409     hr = IXMLDOMAttribute_get_xml(attr, &str);
8410     ok( hr == S_OK, "got 0x%08x\n", hr);
8411     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8412         "got %s\n", wine_dbgstr_w(str));
8413     SysFreeString(str);
8414
8415     ret_attr = (void*)0xdeadbeef;
8416     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8417     ok(hr == S_OK, "got 0x%08x\n", hr);
8418     ok(ret_attr == NULL, "got %p\n", ret_attr);
8419
8420     /* attribute reference increased */
8421     ref2 = IXMLDOMAttribute_AddRef(attr);
8422     IXMLDOMAttribute_Release(attr);
8423     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8424
8425     hr = IXMLDOMElement_get_xml(elem, &str);
8426     ok( hr == S_OK, "got 0x%08x\n", hr);
8427     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8428         "got %s\n", wine_dbgstr_w(str));
8429     SysFreeString(str);
8430
8431     V_VT(&v) = VT_BSTR;
8432     V_BSTR(&v) = _bstr_("attrvalue2");
8433     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8434     ok( hr == S_OK, "got 0x%08x\n", hr);
8435
8436     hr = IXMLDOMElement_get_xml(elem, &str);
8437     ok( hr == S_OK, "got 0x%08x\n", hr);
8438     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8439         "got %s\n", wine_dbgstr_w(str));
8440     SysFreeString(str);
8441
8442     IXMLDOMElement_Release(elem);
8443     IXMLDOMAttribute_Release(attr);
8444     IXMLDOMDocument_Release(doc2);
8445     IXMLDOMDocument_Release(doc);
8446     free_bstrs();
8447 }
8448
8449 static void test_put_dataType(void)
8450 {
8451     IXMLDOMCDATASection *cdata;
8452     IXMLDOMDocument *doc;
8453     VARIANT_BOOL b;
8454     HRESULT hr;
8455
8456     doc = create_document(&IID_IXMLDOMDocument);
8457     if (!doc) return;
8458
8459     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8460     ok( hr == S_OK, "loadXML failed\n");
8461     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8462
8463     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
8464     ok( hr == S_OK, "got 0x%08x\n", hr);
8465     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
8466     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8467     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
8468     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8469     IXMLDOMCDATASection_Release(cdata);
8470
8471     IXMLDOMDocument_Release(doc);
8472     free_bstrs();
8473 }
8474
8475 static void test_createNode(void)
8476 {
8477     IXMLDOMDocument *doc;
8478     IXMLDOMElement *elem;
8479     IXMLDOMNode *node;
8480     VARIANT v, var;
8481     BSTR prefix, str;
8482     HRESULT hr;
8483     ULONG ref;
8484
8485     doc = create_document(&IID_IXMLDOMDocument);
8486     if (!doc) return;
8487
8488     EXPECT_REF(doc, 1);
8489
8490     /* reference count tests */
8491     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8492     ok( hr == S_OK, "got 0x%08x\n", hr);
8493
8494     /* initial reference is 2 */
8495 todo_wine {
8496     EXPECT_REF(elem, 2);
8497     ref = IXMLDOMElement_Release(elem);
8498     ok(ref == 1, "got %d\n", ref);
8499     /* it's released already, attempt to release now will crash it */
8500 }
8501
8502     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8503     ok( hr == S_OK, "got 0x%08x\n", hr);
8504     todo_wine EXPECT_REF(elem, 2);
8505     IXMLDOMDocument_Release(doc);
8506     todo_wine EXPECT_REF(elem, 2);
8507     IXMLDOMElement_Release(elem);
8508
8509     doc = create_document(&IID_IXMLDOMDocument);
8510
8511     /* NODE_ELEMENT nodes */
8512     /* 1. specified namespace */
8513     V_VT(&v) = VT_I4;
8514     V_I4(&v) = NODE_ELEMENT;
8515
8516     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8517     ok( hr == S_OK, "got 0x%08x\n", hr);
8518     prefix = NULL;
8519     hr = IXMLDOMNode_get_prefix(node, &prefix);
8520     ok( hr == S_OK, "got 0x%08x\n", hr);
8521     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8522     SysFreeString(prefix);
8523     IXMLDOMNode_Release(node);
8524
8525     /* 2. default namespace */
8526     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8527     ok( hr == S_OK, "got 0x%08x\n", hr);
8528     prefix = (void*)0xdeadbeef;
8529     hr = IXMLDOMNode_get_prefix(node, &prefix);
8530     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8531     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8532     /* check dump */
8533     hr = IXMLDOMNode_get_xml(node, &str);
8534     ok( hr == S_OK, "got 0x%08x\n", hr);
8535     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8536         "got %s\n", wine_dbgstr_w(str));
8537     SysFreeString(str);
8538
8539     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8540     ok( hr == S_OK, "got 0x%08x\n", hr);
8541
8542     V_VT(&var) = VT_BSTR;
8543     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8544     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8545     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8546
8547     str = NULL;
8548     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8549     ok( hr == S_OK, "got 0x%08x\n", hr);
8550     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8551     SysFreeString(str);
8552
8553     IXMLDOMElement_Release(elem);
8554     IXMLDOMNode_Release(node);
8555
8556     IXMLDOMDocument_Release(doc);
8557     free_bstrs();
8558 }
8559
8560 static const char get_prefix_doc[] =
8561     "<?xml version=\"1.0\" ?>"
8562     "<a xmlns:ns1=\"ns1 href\" />";
8563
8564 static void test_get_prefix(void)
8565 {
8566     IXMLDOMDocumentFragment *fragment;
8567     IXMLDOMCDATASection *cdata;
8568     IXMLDOMElement *element;
8569     IXMLDOMComment *comment;
8570     IXMLDOMDocument *doc;
8571     VARIANT_BOOL b;
8572     HRESULT hr;
8573     BSTR str;
8574
8575     doc = create_document(&IID_IXMLDOMDocument);
8576     if (!doc) return;
8577
8578     /* nodes that can't support prefix */
8579     /* 1. document */
8580     str = (void*)0xdeadbeef;
8581     hr = IXMLDOMDocument_get_prefix(doc, &str);
8582     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8583     ok( str == 0, "got %p\n", str);
8584
8585     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8586     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8587
8588     /* 2. cdata */
8589     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8590     ok(hr == S_OK, "got %08x\n", hr );
8591
8592     str = (void*)0xdeadbeef;
8593     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8594     ok(hr == S_FALSE, "got %08x\n", hr);
8595     ok( str == 0, "got %p\n", str);
8596
8597     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8598     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8599     IXMLDOMCDATASection_Release(cdata);
8600
8601     /* 3. comment */
8602     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8603     ok(hr == S_OK, "got %08x\n", hr );
8604
8605     str = (void*)0xdeadbeef;
8606     hr = IXMLDOMComment_get_prefix(comment, &str);
8607     ok(hr == S_FALSE, "got %08x\n", hr);
8608     ok( str == 0, "got %p\n", str);
8609
8610     hr = IXMLDOMComment_get_prefix(comment, NULL);
8611     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8612     IXMLDOMComment_Release(comment);
8613
8614     /* 4. fragment */
8615     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8616     ok(hr == S_OK, "got %08x\n", hr );
8617
8618     str = (void*)0xdeadbeef;
8619     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8620     ok(hr == S_FALSE, "got %08x\n", hr);
8621     ok( str == 0, "got %p\n", str);
8622
8623     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8624     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8625     IXMLDOMDocumentFragment_Release(fragment);
8626
8627     /* no prefix */
8628     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8629     ok( hr == S_OK, "got 0x%08x\n", hr);
8630
8631     hr = IXMLDOMElement_get_prefix(element, NULL);
8632     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8633
8634     str = (void*)0xdeadbeef;
8635     hr = IXMLDOMElement_get_prefix(element, &str);
8636     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8637     ok( str == 0, "got %p\n", str);
8638
8639     IXMLDOMElement_Release(element);
8640
8641     /* with prefix */
8642     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8643     ok( hr == S_OK, "got 0x%08x\n", hr);
8644
8645     str = (void*)0xdeadbeef;
8646     hr = IXMLDOMElement_get_prefix(element, &str);
8647     ok( hr == S_OK, "got 0x%08x\n", hr);
8648     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8649     SysFreeString(str);
8650
8651     str = (void*)0xdeadbeef;
8652     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8653     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8654     ok( str == 0, "got %p\n", str);
8655
8656     IXMLDOMElement_Release(element);
8657
8658     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8659     EXPECT_HR(hr, S_OK);
8660
8661     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8662     EXPECT_HR(hr, S_OK);
8663
8664     str = (void*)0xdeadbeef;
8665     hr = IXMLDOMElement_get_prefix(element, &str);
8666     EXPECT_HR(hr, S_FALSE);
8667     ok(str == NULL, "got %p\n", str);
8668
8669     str = (void*)0xdeadbeef;
8670     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8671     EXPECT_HR(hr, S_FALSE);
8672     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8673
8674     IXMLDOMDocument_Release(doc);
8675     free_bstrs();
8676 }
8677
8678 static void test_selectSingleNode(void)
8679 {
8680     IXMLDOMDocument *doc;
8681     IXMLDOMNodeList *list;
8682     IXMLDOMNode *node;
8683     VARIANT_BOOL b;
8684     HRESULT hr;
8685     LONG len;
8686
8687     doc = create_document(&IID_IXMLDOMDocument);
8688     if (!doc) return;
8689
8690     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8691     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8692
8693     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8694     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8695
8696     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8697     ok( hr == S_OK, "loadXML failed\n");
8698     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8699
8700     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8701     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8702
8703     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8704     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8705
8706     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8707     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8708
8709     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8710     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8711
8712     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8713     ok(hr == S_OK, "got 0x%08x\n", hr);
8714     IXMLDOMNode_Release(node);
8715
8716     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8717     ok(hr == S_OK, "got 0x%08x\n", hr);
8718     IXMLDOMNodeList_Release(list);
8719
8720     list = (void*)0xdeadbeef;
8721     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8722     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8723     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8724
8725     node = (void*)0xdeadbeef;
8726     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8727     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8728     ok(node == 0, "got %p\n", node);
8729
8730     list = (void*)0xdeadbeef;
8731     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8732     ok(hr == S_OK, "got 0x%08x\n", hr);
8733     len = 1;
8734     hr = IXMLDOMNodeList_get_length(list, &len);
8735     ok(hr == S_OK, "got 0x%08x\n", hr);
8736     ok(len == 0, "got %d\n", len);
8737     IXMLDOMNodeList_Release(list);
8738
8739     IXMLDOMDocument_Release(doc);
8740     free_bstrs();
8741 }
8742
8743 static void test_events(void)
8744 {
8745     IConnectionPointContainer *conn;
8746     IConnectionPoint *point;
8747     IXMLDOMDocument *doc;
8748     HRESULT hr;
8749     VARIANT v;
8750     IDispatch *event;
8751
8752     doc = create_document(&IID_IXMLDOMDocument);
8753     if (!doc) return;
8754
8755     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8756     ok(hr == S_OK, "got 0x%08x\n", hr);
8757
8758     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8759     ok(hr == S_OK, "got 0x%08x\n", hr);
8760     IConnectionPoint_Release(point);
8761     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8762     ok(hr == S_OK, "got 0x%08x\n", hr);
8763     IConnectionPoint_Release(point);
8764     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8765     ok(hr == S_OK, "got 0x%08x\n", hr);
8766     IConnectionPoint_Release(point);
8767
8768     IConnectionPointContainer_Release(conn);
8769
8770     /* ready state callback */
8771     VariantInit(&v);
8772     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8773     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8774
8775     event = create_dispevent();
8776     V_VT(&v) = VT_UNKNOWN;
8777     V_UNKNOWN(&v) = (IUnknown*)event;
8778
8779     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8780     ok(hr == S_OK, "got 0x%08x\n", hr);
8781     EXPECT_REF(event, 2);
8782
8783     V_VT(&v) = VT_DISPATCH;
8784     V_DISPATCH(&v) = event;
8785
8786     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8787     ok(hr == S_OK, "got 0x%08x\n", hr);
8788     EXPECT_REF(event, 2);
8789
8790     /* VT_NULL doesn't reset event handler */
8791     V_VT(&v) = VT_NULL;
8792     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8793     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8794     EXPECT_REF(event, 2);
8795
8796     V_VT(&v) = VT_DISPATCH;
8797     V_DISPATCH(&v) = NULL;
8798
8799     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8800     ok(hr == S_OK, "got 0x%08x\n", hr);
8801     EXPECT_REF(event, 1);
8802
8803     V_VT(&v) = VT_UNKNOWN;
8804     V_DISPATCH(&v) = NULL;
8805     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8806     ok(hr == S_OK, "got 0x%08x\n", hr);
8807
8808     IDispatch_Release(event);
8809
8810     IXMLDOMDocument_Release(doc);
8811 }
8812
8813 static void test_createProcessingInstruction(void)
8814 {
8815     static const WCHAR bodyW[] = {'t','e','s','t',0};
8816     IXMLDOMProcessingInstruction *pi;
8817     IXMLDOMDocument *doc;
8818     WCHAR buff[10];
8819     HRESULT hr;
8820
8821     doc = create_document(&IID_IXMLDOMDocument);
8822     if (!doc) return;
8823
8824     /* test for BSTR handling, pass broken BSTR */
8825     memcpy(&buff[2], bodyW, sizeof(bodyW));
8826     /* just a big length */
8827     *(DWORD*)buff = 0xf0f0;
8828     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
8829     ok(hr == S_OK, "got 0x%08x\n", hr);
8830
8831     IXMLDOMProcessingInstruction_Release(pi);
8832     IXMLDOMDocument_Release(doc);
8833 }
8834
8835 static void test_put_nodeTypedValue(void)
8836 {
8837     IXMLDOMDocument *doc;
8838     IXMLDOMElement *elem;
8839     VARIANT type;
8840     HRESULT hr;
8841
8842     doc = create_document(&IID_IXMLDOMDocument);
8843     if (!doc) return;
8844
8845     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
8846     ok(hr == S_OK, "got 0x%08x\n", hr);
8847
8848     V_VT(&type) = VT_EMPTY;
8849     hr = IXMLDOMElement_get_dataType(elem, &type);
8850     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8851     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8852
8853     /* set typed value for untyped node */
8854     V_VT(&type) = VT_I1;
8855     V_I1(&type) = 1;
8856     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
8857     ok(hr == S_OK, "got 0x%08x\n", hr);
8858
8859     V_VT(&type) = VT_EMPTY;
8860     hr = IXMLDOMElement_get_dataType(elem, &type);
8861     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8862     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8863
8864     /* no type info stored */
8865     V_VT(&type) = VT_EMPTY;
8866     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
8867     ok(hr == S_OK, "got 0x%08x\n", hr);
8868     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
8869     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
8870        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
8871     VariantClear(&type);
8872
8873     IXMLDOMElement_Release(elem);
8874     IXMLDOMDocument_Release(doc);
8875     free_bstrs();
8876 }
8877
8878 static void test_get_xml(void)
8879 {
8880     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
8881     static const char fooA[] = "<foo/>";
8882     IXMLDOMProcessingInstruction *pi;
8883     IXMLDOMNode *first;
8884     IXMLDOMElement *elem = NULL;
8885     IXMLDOMDocument *doc;
8886     VARIANT_BOOL b;
8887     VARIANT v;
8888     BSTR xml;
8889     HRESULT hr;
8890
8891     doc = create_document(&IID_IXMLDOMDocument);
8892     if (!doc) return;
8893
8894     b = VARIANT_TRUE;
8895     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8896     ok(hr == S_OK, "got 0x%08x\n", hr);
8897     ok( b == VARIANT_TRUE, "got %d\n", b);
8898
8899     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
8900                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
8901     ok(hr == S_OK, "got 0x%08x\n", hr);
8902
8903     hr = IXMLDOMDocument_get_firstChild(doc, &first);
8904     ok(hr == S_OK, "got 0x%08x\n", hr);
8905
8906     V_UNKNOWN(&v) = (IUnknown*)first;
8907     V_VT(&v) = VT_UNKNOWN;
8908
8909     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
8910     ok(hr == S_OK, "got 0x%08x\n", hr);
8911
8912     IXMLDOMProcessingInstruction_Release(pi);
8913     IXMLDOMNode_Release(first);
8914
8915     hr = IXMLDOMDocument_get_xml(doc, &xml);
8916     ok(hr == S_OK, "got 0x%08x\n", hr);
8917
8918     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
8919         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
8920     SysFreeString(xml);
8921
8922     IXMLDOMDocument_Release(doc);
8923
8924     doc = create_document(&IID_IXMLDOMDocument);
8925
8926     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
8927     ok(hr == S_OK, "got 0x%08x\n", hr);
8928
8929     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
8930     ok(hr == S_OK, "got 0x%08x\n", hr);
8931
8932     hr = IXMLDOMDocument_get_xml(doc, &xml);
8933     ok(hr == S_OK, "got 0x%08x\n", hr);
8934
8935     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
8936         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
8937     SysFreeString(xml);
8938
8939     IXMLDOMElement_Release(elem);
8940     IXMLDOMDocument_Release(doc);
8941
8942     free_bstrs();
8943 }
8944
8945 static void test_xsltemplate(void)
8946 {
8947     IXSLTemplate *template;
8948     IXSLProcessor *processor;
8949     IXMLDOMDocument *doc, *doc2;
8950     IStream *stream;
8951     VARIANT_BOOL b;
8952     HRESULT hr;
8953     ULONG ref1, ref2;
8954     VARIANT v;
8955
8956     template = create_xsltemplate(&IID_IXSLTemplate);
8957     if (!template) return;
8958
8959     /* works as reset */
8960     hr = IXSLTemplate_putref_stylesheet(template, NULL);
8961     ok(hr == S_OK, "got 0x%08x\n", hr);
8962
8963     doc = create_document(&IID_IXMLDOMDocument);
8964
8965     b = VARIANT_TRUE;
8966     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8967     ok(hr == S_OK, "got 0x%08x\n", hr);
8968     ok( b == VARIANT_TRUE, "got %d\n", b);
8969
8970     /* putref with non-xsl document */
8971     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8972     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8973
8974     b = VARIANT_TRUE;
8975     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8976     ok(hr == S_OK, "got 0x%08x\n", hr);
8977     ok( b == VARIANT_TRUE, "got %d\n", b);
8978
8979     /* not a freethreaded document */
8980     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8981     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8982
8983     IXMLDOMDocument_Release(doc);
8984
8985     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
8986     if (hr != S_OK)
8987     {
8988         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
8989         IXSLTemplate_Release(template);
8990         return;
8991     }
8992
8993     b = VARIANT_TRUE;
8994     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8995     ok(hr == S_OK, "got 0x%08x\n", hr);
8996     ok( b == VARIANT_TRUE, "got %d\n", b);
8997
8998     /* freethreaded document */
8999     ref1 = IXMLDOMDocument_AddRef(doc);
9000     IXMLDOMDocument_Release(doc);
9001     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9002     ok(hr == S_OK, "got 0x%08x\n", hr);
9003     ref2 = IXMLDOMDocument_AddRef(doc);
9004     IXMLDOMDocument_Release(doc);
9005     ok(ref2 > ref1, "got %d\n", ref2);
9006
9007     /* processor */
9008     hr = IXSLTemplate_createProcessor(template, NULL);
9009     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9010
9011     EXPECT_REF(template, 1);
9012     hr = IXSLTemplate_createProcessor(template, &processor);
9013     ok(hr == S_OK, "got 0x%08x\n", hr);
9014     EXPECT_REF(template, 2);
9015
9016     /* input no set yet */
9017     V_VT(&v) = VT_BSTR;
9018     V_BSTR(&v) = NULL;
9019     hr = IXSLProcessor_get_input(processor, &v);
9020 todo_wine {
9021     ok(hr == S_OK, "got 0x%08x\n", hr);
9022     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9023 }
9024
9025     hr = IXSLProcessor_get_output(processor, NULL);
9026     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9027
9028     /* reset before it was set */
9029     V_VT(&v) = VT_EMPTY;
9030     hr = IXSLProcessor_put_output(processor, v);
9031     ok(hr == S_OK, "got 0x%08x\n", hr);
9032
9033     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9034     EXPECT_REF(stream, 1);
9035
9036     V_VT(&v) = VT_UNKNOWN;
9037     V_UNKNOWN(&v) = (IUnknown*)stream;
9038     hr = IXSLProcessor_put_output(processor, v);
9039     ok(hr == S_OK, "got 0x%08x\n", hr);
9040
9041     /* it seems processor grabs 2 references */
9042     todo_wine EXPECT_REF(stream, 3);
9043
9044     V_VT(&v) = VT_EMPTY;
9045     hr = IXSLProcessor_get_output(processor, &v);
9046     ok(hr == S_OK, "got 0x%08x\n", hr);
9047     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9048     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9049
9050     todo_wine EXPECT_REF(stream, 4);
9051     VariantClear(&v);
9052
9053     hr = IXSLProcessor_transform(processor, NULL);
9054     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9055
9056     /* reset and check stream refcount */
9057     V_VT(&v) = VT_EMPTY;
9058     hr = IXSLProcessor_put_output(processor, v);
9059     ok(hr == S_OK, "got 0x%08x\n", hr);
9060
9061     EXPECT_REF(stream, 1);
9062
9063     IStream_Release(stream);
9064
9065     /* no output interface set, check output */
9066     doc2 = create_document(&IID_IXMLDOMDocument);
9067
9068     b = VARIANT_TRUE;
9069     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9070     ok(hr == S_OK, "got 0x%08x\n", hr);
9071     ok( b == VARIANT_TRUE, "got %d\n", b);
9072
9073     V_VT(&v) = VT_UNKNOWN;
9074     V_UNKNOWN(&v) = (IUnknown*)doc2;
9075     hr = IXSLProcessor_put_input(processor, v);
9076     ok(hr == S_OK, "got 0x%08x\n", hr);
9077
9078     hr = IXSLProcessor_transform(processor, &b);
9079     ok(hr == S_OK, "got 0x%08x\n", hr);
9080
9081     V_VT(&v) = VT_EMPTY;
9082     hr = IXSLProcessor_get_output(processor, &v);
9083     ok(hr == S_OK, "got 0x%08x\n", hr);
9084     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9085     /* we currently output one '\n' instead of empty string */
9086     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9087     IXMLDOMDocument_Release(doc2);
9088     VariantClear(&v);
9089
9090     IXSLProcessor_Release(processor);
9091
9092     /* drop reference */
9093     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9094     ok(hr == S_OK, "got 0x%08x\n", hr);
9095     ref2 = IXMLDOMDocument_AddRef(doc);
9096     IXMLDOMDocument_Release(doc);
9097     ok(ref2 == ref1, "got %d\n", ref2);
9098
9099     IXMLDOMDocument_Release(doc);
9100     IXSLTemplate_Release(template);
9101     free_bstrs();
9102 }
9103
9104 static void test_insertBefore(void)
9105 {
9106     IXMLDOMDocument *doc, *doc2;
9107     IXMLDOMAttribute *attr;
9108     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9109     IXMLDOMNode *node, *newnode;
9110     HRESULT hr;
9111     VARIANT v;
9112     BSTR p;
9113
9114     doc = create_document(&IID_IXMLDOMDocument);
9115
9116     /* insertBefore behaviour for attribute node */
9117     V_VT(&v) = VT_I4;
9118     V_I4(&v) = NODE_ATTRIBUTE;
9119
9120     attr = NULL;
9121     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9122     ok(hr == S_OK, "got 0x%08x\n", hr);
9123     ok(attr != NULL, "got %p\n", attr);
9124
9125     /* attribute to attribute */
9126     V_VT(&v) = VT_I4;
9127     V_I4(&v) = NODE_ATTRIBUTE;
9128     newnode = NULL;
9129     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9130     ok(hr == S_OK, "got 0x%08x\n", hr);
9131     ok(newnode != NULL, "got %p\n", newnode);
9132
9133     V_VT(&v) = VT_NULL;
9134     node = (void*)0xdeadbeef;
9135     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9136     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9137     ok(node == NULL, "got %p\n", node);
9138
9139     V_VT(&v) = VT_UNKNOWN;
9140     V_UNKNOWN(&v) = (IUnknown*)attr;
9141     node = (void*)0xdeadbeef;
9142     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9143     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9144     ok(node == NULL, "got %p\n", node);
9145     IXMLDOMNode_Release(newnode);
9146
9147     /* cdata to attribute */
9148     V_VT(&v) = VT_I4;
9149     V_I4(&v) = NODE_CDATA_SECTION;
9150     newnode = NULL;
9151     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9152     ok(hr == S_OK, "got 0x%08x\n", hr);
9153     ok(newnode != NULL, "got %p\n", newnode);
9154
9155     V_VT(&v) = VT_NULL;
9156     node = (void*)0xdeadbeef;
9157     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9158     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9159     ok(node == NULL, "got %p\n", node);
9160     IXMLDOMNode_Release(newnode);
9161
9162     /* comment to attribute */
9163     V_VT(&v) = VT_I4;
9164     V_I4(&v) = NODE_COMMENT;
9165     newnode = NULL;
9166     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9167     ok(hr == S_OK, "got 0x%08x\n", hr);
9168     ok(newnode != NULL, "got %p\n", newnode);
9169
9170     V_VT(&v) = VT_NULL;
9171     node = (void*)0xdeadbeef;
9172     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9173     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9174     ok(node == NULL, "got %p\n", node);
9175     IXMLDOMNode_Release(newnode);
9176
9177     /* element to attribute */
9178     V_VT(&v) = VT_I4;
9179     V_I4(&v) = NODE_ELEMENT;
9180     newnode = NULL;
9181     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9182     ok(hr == S_OK, "got 0x%08x\n", hr);
9183     ok(newnode != NULL, "got %p\n", newnode);
9184
9185     V_VT(&v) = VT_NULL;
9186     node = (void*)0xdeadbeef;
9187     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9188     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9189     ok(node == NULL, "got %p\n", node);
9190     IXMLDOMNode_Release(newnode);
9191
9192     /* pi to attribute */
9193     V_VT(&v) = VT_I4;
9194     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9195     newnode = NULL;
9196     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9197     ok(hr == S_OK, "got 0x%08x\n", hr);
9198     ok(newnode != NULL, "got %p\n", newnode);
9199
9200     V_VT(&v) = VT_NULL;
9201     node = (void*)0xdeadbeef;
9202     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9203     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9204     ok(node == NULL, "got %p\n", node);
9205     IXMLDOMNode_Release(newnode);
9206     IXMLDOMAttribute_Release(attr);
9207
9208     /* insertBefore for elements */
9209     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9210     ok(hr == S_OK, "got 0x%08x\n", hr);
9211
9212     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9213     ok(hr == S_OK, "got 0x%08x\n", hr);
9214
9215     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9216     ok(hr == S_OK, "got 0x%08x\n", hr);
9217
9218     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9219     ok(hr == S_OK, "got 0x%08x\n", hr);
9220
9221     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9222     ok(hr == S_OK, "got 0x%08x\n", hr);
9223
9224     EXPECT_NO_CHILDREN(elem1);
9225     EXPECT_NO_CHILDREN(elem2);
9226     EXPECT_NO_CHILDREN(elem3);
9227
9228     todo_wine EXPECT_REF(elem2, 2);
9229
9230     V_VT(&v) = VT_DISPATCH;
9231     V_DISPATCH(&v) = NULL;
9232     node = NULL;
9233     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9234     ok(hr == S_OK, "got 0x%08x\n", hr);
9235     ok(node == (void*)elem4, "got %p\n", node);
9236
9237     EXPECT_CHILDREN(elem1);
9238     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9239     EXPECT_HR(hr, S_OK);
9240     IXMLDOMElement_Release(elem4);
9241
9242     EXPECT_NO_CHILDREN(elem1);
9243
9244     V_VT(&v) = VT_NULL;
9245     node = NULL;
9246     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9247     ok(hr == S_OK, "got 0x%08x\n", hr);
9248     ok(node == (void*)elem2, "got %p\n", node);
9249
9250     EXPECT_CHILDREN(elem1);
9251     todo_wine EXPECT_REF(elem2, 3);
9252     IXMLDOMNode_Release(node);
9253
9254     /* again for already linked node */
9255     V_VT(&v) = VT_NULL;
9256     node = NULL;
9257     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9258     ok(hr == S_OK, "got 0x%08x\n", hr);
9259     ok(node == (void*)elem2, "got %p\n", node);
9260
9261     EXPECT_CHILDREN(elem1);
9262
9263     /* increments each time */
9264     todo_wine EXPECT_REF(elem2, 3);
9265     IXMLDOMNode_Release(node);
9266
9267     /* try to add to another element */
9268     V_VT(&v) = VT_NULL;
9269     node = (void*)0xdeadbeef;
9270     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9271     ok(hr == S_OK, "got 0x%08x\n", hr);
9272     ok(node == (void*)elem2, "got %p\n", node);
9273
9274     EXPECT_CHILDREN(elem3);
9275     EXPECT_NO_CHILDREN(elem1);
9276
9277     IXMLDOMNode_Release(node);
9278
9279     /* cross document case - try to add as child to a node created with other doc */
9280     doc2 = create_document(&IID_IXMLDOMDocument);
9281
9282     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9283     ok(hr == S_OK, "got 0x%08x\n", hr);
9284     todo_wine EXPECT_REF(elem4, 2);
9285
9286     /* same name, another instance */
9287     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9288     ok(hr == S_OK, "got 0x%08x\n", hr);
9289     todo_wine EXPECT_REF(elem5, 2);
9290
9291     todo_wine EXPECT_REF(elem3, 2);
9292     V_VT(&v) = VT_NULL;
9293     node = NULL;
9294     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9295     ok(hr == S_OK, "got 0x%08x\n", hr);
9296     ok(node == (void*)elem4, "got %p\n", node);
9297     todo_wine EXPECT_REF(elem4, 3);
9298     todo_wine EXPECT_REF(elem3, 2);
9299     IXMLDOMNode_Release(node);
9300
9301     V_VT(&v) = VT_NULL;
9302     node = NULL;
9303     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9304     ok(hr == S_OK, "got 0x%08x\n", hr);
9305     ok(node == (void*)elem5, "got %p\n", node);
9306     todo_wine EXPECT_REF(elem4, 2);
9307     todo_wine EXPECT_REF(elem5, 3);
9308     IXMLDOMNode_Release(node);
9309
9310     IXMLDOMDocument_Release(doc2);
9311
9312     IXMLDOMElement_Release(elem1);
9313     IXMLDOMElement_Release(elem2);
9314     IXMLDOMElement_Release(elem3);
9315     IXMLDOMElement_Release(elem4);
9316     IXMLDOMElement_Release(elem5);
9317
9318     /* elements with same default namespace */
9319     V_VT(&v) = VT_I4;
9320     V_I4(&v) = NODE_ELEMENT;
9321     elem1 = NULL;
9322     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9323     ok(hr == S_OK, "got 0x%08x\n", hr);
9324     ok(elem1 != NULL, "got %p\n", elem1);
9325
9326     V_VT(&v) = VT_I4;
9327     V_I4(&v) = NODE_ELEMENT;
9328     elem2 = NULL;
9329     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9330     ok(hr == S_OK, "got 0x%08x\n", hr);
9331     ok(elem2 != NULL, "got %p\n", elem2);
9332
9333     /* check contents so far */
9334     p = NULL;
9335     hr = IXMLDOMElement_get_xml(elem1, &p);
9336     ok(hr == S_OK, "got 0x%08x\n", hr);
9337     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9338     SysFreeString(p);
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 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9344     SysFreeString(p);
9345
9346     V_VT(&v) = VT_NULL;
9347     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9348     ok(hr == S_OK, "got 0x%08x\n", hr);
9349
9350     /* get_xml depends on context, for top node it omits child namespace attribute,
9351        but at child level it's still returned */
9352     p = NULL;
9353     hr = IXMLDOMElement_get_xml(elem1, &p);
9354     ok(hr == S_OK, "got 0x%08x\n", hr);
9355     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9356         "got %s\n", wine_dbgstr_w(p));
9357     SysFreeString(p);
9358
9359     p = NULL;
9360     hr = IXMLDOMElement_get_xml(elem2, &p);
9361     ok(hr == S_OK, "got 0x%08x\n", hr);
9362     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9363     SysFreeString(p);
9364
9365     IXMLDOMElement_Release(elem1);
9366     IXMLDOMElement_Release(elem2);
9367
9368     /* child without default namespace added to node with default namespace */
9369     V_VT(&v) = VT_I4;
9370     V_I4(&v) = NODE_ELEMENT;
9371     elem1 = NULL;
9372     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9373     ok(hr == S_OK, "got 0x%08x\n", hr);
9374     ok(elem1 != NULL, "got %p\n", elem1);
9375
9376     V_VT(&v) = VT_I4;
9377     V_I4(&v) = NODE_ELEMENT;
9378     elem2 = NULL;
9379     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9380     ok(hr == S_OK, "got 0x%08x\n", hr);
9381     ok(elem2 != NULL, "got %p\n", elem2);
9382
9383     EXPECT_REF(elem2, 1);
9384     V_VT(&v) = VT_NULL;
9385     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9386     ok(hr == S_OK, "got 0x%08x\n", hr);
9387     EXPECT_REF(elem2, 1);
9388
9389     p = NULL;
9390     hr = IXMLDOMElement_get_xml(elem2, &p);
9391     ok(hr == S_OK, "got 0x%08x\n", hr);
9392     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9393     SysFreeString(p);
9394
9395     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9396     ok(hr == S_OK, "got 0x%08x\n", hr);
9397
9398     p = NULL;
9399     hr = IXMLDOMElement_get_xml(elem2, &p);
9400     ok(hr == S_OK, "got 0x%08x\n", hr);
9401     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9402     SysFreeString(p);
9403
9404     IXMLDOMElement_Release(elem1);
9405     IXMLDOMElement_Release(elem2);
9406     IXMLDOMDocument_Release(doc);
9407 }
9408
9409 static void test_appendChild(void)
9410 {
9411     IXMLDOMDocument *doc, *doc2;
9412     IXMLDOMElement *elem, *elem2;
9413     HRESULT hr;
9414
9415     doc = create_document(&IID_IXMLDOMDocument);
9416     doc2 = create_document(&IID_IXMLDOMDocument);
9417
9418     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9419     ok(hr == S_OK, "got 0x%08x\n", hr);
9420
9421     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9422     ok(hr == S_OK, "got 0x%08x\n", hr);
9423
9424     EXPECT_REF(doc, 1);
9425     todo_wine EXPECT_REF(elem, 2);
9426     EXPECT_REF(doc2, 1);
9427     todo_wine EXPECT_REF(elem2, 2);
9428     EXPECT_NO_CHILDREN(doc);
9429     EXPECT_NO_CHILDREN(doc2);
9430
9431     /* append from another document */
9432     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9433     ok(hr == S_OK, "got 0x%08x\n", hr);
9434
9435     EXPECT_REF(doc, 1);
9436     todo_wine EXPECT_REF(elem, 2);
9437     EXPECT_REF(doc2, 1);
9438     todo_wine EXPECT_REF(elem2, 2);
9439     EXPECT_NO_CHILDREN(doc);
9440     EXPECT_CHILDREN(doc2);
9441
9442     IXMLDOMElement_Release(elem);
9443     IXMLDOMElement_Release(elem2);
9444     IXMLDOMDocument_Release(doc);
9445     IXMLDOMDocument_Release(doc2);
9446 }
9447
9448 static void test_get_doctype(void)
9449 {
9450     IXMLDOMDocumentType *doctype;
9451     IXMLDOMDocument *doc;
9452     HRESULT hr;
9453
9454     doc = create_document(&IID_IXMLDOMDocument);
9455
9456     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9457     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9458
9459     doctype = (void*)0xdeadbeef;
9460     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9461     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9462     ok(doctype == NULL, "got %p\n", doctype);
9463
9464     IXMLDOMDocument_Release(doc);
9465 }
9466
9467 static void test_get_tagName(void)
9468 {
9469     IXMLDOMDocument *doc;
9470     IXMLDOMElement *elem, *elem2;
9471     HRESULT hr;
9472     BSTR str;
9473
9474     doc = create_document(&IID_IXMLDOMDocument);
9475
9476     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9477     ok(hr == S_OK, "got 0x%08x\n", hr);
9478
9479     hr = IXMLDOMElement_get_tagName(elem, NULL);
9480     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9481
9482     str = NULL;
9483     hr = IXMLDOMElement_get_tagName(elem, &str);
9484     ok(hr == S_OK, "got 0x%08x\n", hr);
9485     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9486     SysFreeString(str);
9487
9488     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9489     ok(hr == S_OK, "got 0x%08x\n", hr);
9490
9491     str = NULL;
9492     hr = IXMLDOMElement_get_tagName(elem2, &str);
9493     ok(hr == S_OK, "got 0x%08x\n", hr);
9494     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9495     SysFreeString(str);
9496
9497     IXMLDOMDocument_Release(elem);
9498     IXMLDOMDocument_Release(elem2);
9499     IXMLDOMDocument_Release(doc);
9500     free_bstrs();
9501 }
9502
9503 typedef struct _get_datatype_t {
9504     DOMNodeType type;
9505     const char *name;
9506     VARTYPE vt;
9507     HRESULT hr;
9508 } get_datatype_t;
9509
9510 static const get_datatype_t get_datatype[] = {
9511     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9512     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9513     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9514     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9515     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9516     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9517     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9518     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9519     { 0 }
9520 };
9521
9522 static void test_get_dataType(void)
9523 {
9524     IXMLDOMDocument *doc;
9525     const get_datatype_t *entry = get_datatype;
9526
9527     doc = create_document(&IID_IXMLDOMDocument);
9528
9529     while (entry->type)
9530     {
9531         IXMLDOMNode *node = NULL;
9532         VARIANT var, type;
9533         HRESULT hr;
9534
9535         V_VT(&var) = VT_I4;
9536         V_I4(&var) = entry->type;
9537         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9538         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9539
9540         hr = IXMLDOMNode_get_dataType(node, NULL);
9541         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9542
9543         VariantInit(&type);
9544         hr = IXMLDOMNode_get_dataType(node, &type);
9545         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9546             hr, entry->hr, entry->type);
9547         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9548             V_VT(&type), entry->vt, entry->type);
9549         VariantClear(&type);
9550
9551         IXMLDOMNode_Release(node);
9552
9553         entry++;
9554     }
9555
9556     IXMLDOMDocument_Release(doc);
9557     free_bstrs();
9558 }
9559
9560 typedef struct _get_node_typestring_t {
9561     DOMNodeType type;
9562     const char *string;
9563 } get_node_typestring_t;
9564
9565 static const get_node_typestring_t get_node_typestring[] = {
9566     { NODE_ELEMENT,                "element"               },
9567     { NODE_ATTRIBUTE,              "attribute"             },
9568     { NODE_TEXT,                   "text"                  },
9569     { NODE_CDATA_SECTION ,         "cdatasection"          },
9570     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9571     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9572     { NODE_COMMENT,                "comment"               },
9573     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9574     { 0 }
9575 };
9576
9577 static void test_get_nodeTypeString(void)
9578 {
9579     const get_node_typestring_t *entry = get_node_typestring;
9580     IXMLDOMDocument *doc;
9581     HRESULT hr;
9582     BSTR str;
9583
9584     doc = create_document(&IID_IXMLDOMDocument);
9585
9586     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9587     ok(hr == S_OK, "got 0x%08x\n", hr);
9588     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9589     SysFreeString(str);
9590
9591     while (entry->type)
9592     {
9593         IXMLDOMNode *node = NULL;
9594         VARIANT var;
9595
9596         V_VT(&var) = VT_I4;
9597         V_I4(&var) = entry->type;
9598         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9599         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9600
9601         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9602         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9603
9604         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9605         ok(hr == S_OK, "got 0x%08x\n", hr);
9606         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9607             wine_dbgstr_w(str), entry->string, entry->type);
9608         SysFreeString(str);
9609         IXMLDOMNode_Release(node);
9610
9611         entry++;
9612     }
9613
9614     IXMLDOMDocument_Release(doc);
9615     free_bstrs();
9616 }
9617
9618 typedef struct _get_attributes_t {
9619     DOMNodeType type;
9620     HRESULT hr;
9621 } get_attributes_t;
9622
9623 static const get_attributes_t get_attributes[] = {
9624     { NODE_ATTRIBUTE,              S_FALSE },
9625     { NODE_TEXT,                   S_FALSE },
9626     { NODE_CDATA_SECTION ,         S_FALSE },
9627     { NODE_ENTITY_REFERENCE,       S_FALSE },
9628     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9629     { NODE_COMMENT,                S_FALSE },
9630     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9631     { 0 }
9632 };
9633
9634 static void test_get_attributes(void)
9635 {
9636     const get_attributes_t *entry = get_attributes;
9637     IXMLDOMNamedNodeMap *map;
9638     IXMLDOMDocument *doc;
9639     IXMLDOMNode *node, *node2;
9640     VARIANT_BOOL b;
9641     HRESULT hr;
9642     BSTR str;
9643     LONG length;
9644
9645     doc = create_document(&IID_IXMLDOMDocument);
9646
9647     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9648     ok(hr == S_OK, "got %08x\n", hr);
9649
9650     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9651     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9652
9653     map = (void*)0xdeadbeef;
9654     hr = IXMLDOMDocument_get_attributes(doc, &map);
9655     ok(hr == S_FALSE, "got %08x\n", hr);
9656     ok(map == NULL, "got %p\n", map);
9657
9658     /* first child is <?xml ?> */
9659     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9660     ok(hr == S_OK, "got %08x\n", hr);
9661
9662     hr = IXMLDOMNode_get_attributes(node, &map);
9663     ok(hr == S_OK, "got %08x\n", hr);
9664
9665     length = -1;
9666     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9667     EXPECT_HR(hr, S_OK);
9668     todo_wine ok(length == 1, "got %d\n", length);
9669
9670     if (hr == S_OK && length == 1)
9671     {
9672         IXMLDOMAttribute *attr;
9673         DOMNodeType type;
9674         VARIANT v;
9675
9676         node2 = NULL;
9677         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9678         EXPECT_HR(hr, S_OK);
9679         ok(node != NULL, "got %p\n", node2);
9680
9681         hr = IXMLDOMNode_get_nodeName(node2, &str);
9682         EXPECT_HR(hr, S_OK);
9683         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9684         SysFreeString(str);
9685
9686         length = -1;
9687         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9688         EXPECT_HR(hr, S_OK);
9689         ok(length == 1, "got %d\n", length);
9690
9691         type = -1;
9692         hr = IXMLDOMNode_get_nodeType(node2, &type);
9693         EXPECT_HR(hr, S_OK);
9694         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9695
9696         hr = IXMLDOMNode_get_xml(node, &str);
9697         EXPECT_HR(hr, S_OK);
9698         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9699         SysFreeString(str);
9700
9701         hr = IXMLDOMNode_get_text(node, &str);
9702         EXPECT_HR(hr, S_OK);
9703         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9704         SysFreeString(str);
9705
9706         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9707         EXPECT_HR(hr, S_OK);
9708
9709         length = -1;
9710         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9711         EXPECT_HR(hr, S_OK);
9712         ok(length == 0, "got %d\n", length);
9713
9714         hr = IXMLDOMNode_get_xml(node, &str);
9715         EXPECT_HR(hr, S_OK);
9716         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9717         SysFreeString(str);
9718
9719         hr = IXMLDOMNode_get_text(node, &str);
9720         EXPECT_HR(hr, S_OK);
9721         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9722         SysFreeString(str);
9723
9724         IXMLDOMNamedNodeMap_Release(map);
9725
9726         hr = IXMLDOMNode_get_attributes(node, &map);
9727         ok(hr == S_OK, "got %08x\n", hr);
9728
9729         length = -1;
9730         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9731         EXPECT_HR(hr, S_OK);
9732         ok(length == 0, "got %d\n", length);
9733
9734         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9735         EXPECT_HR(hr, S_OK);
9736
9737         V_VT(&v) = VT_BSTR;
9738         V_BSTR(&v) = _bstr_("UTF-8");
9739         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9740         EXPECT_HR(hr, S_OK);
9741
9742         EXPECT_REF(attr, 2);
9743         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9744         EXPECT_HR(hr, S_OK);
9745         EXPECT_REF(attr, 2);
9746
9747         hr = IXMLDOMNode_get_attributes(node, &map);
9748         ok(hr == S_OK, "got %08x\n", hr);
9749
9750         length = -1;
9751         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9752         EXPECT_HR(hr, S_OK);
9753         ok(length == 1, "got %d\n", length);
9754
9755         hr = IXMLDOMNode_get_xml(node, &str);
9756         EXPECT_HR(hr, S_OK);
9757         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9758         SysFreeString(str);
9759
9760         hr = IXMLDOMNode_get_text(node, &str);
9761         EXPECT_HR(hr, S_OK);
9762         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9763         SysFreeString(str);
9764
9765         IXMLDOMNamedNodeMap_Release(map);
9766         IXMLDOMNode_Release(node2);
9767     }
9768
9769     IXMLDOMNode_Release(node);
9770
9771     /* last child is element */
9772     EXPECT_REF(doc, 1);
9773     hr = IXMLDOMDocument_get_lastChild(doc, &node);
9774     ok(hr == S_OK, "got %08x\n", hr);
9775     EXPECT_REF(doc, 1);
9776
9777     EXPECT_REF(node, 1);
9778     hr = IXMLDOMNode_get_attributes(node, &map);
9779     ok(hr == S_OK, "got %08x\n", hr);
9780     EXPECT_REF(node, 1);
9781     EXPECT_REF(doc, 1);
9782
9783     EXPECT_REF(map, 1);
9784     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9785     ok(hr == S_OK, "got %08x\n", hr);
9786     EXPECT_REF(node, 1);
9787     EXPECT_REF(node2, 1);
9788     EXPECT_REF(map, 1);
9789     EXPECT_REF(doc, 1);
9790     IXMLDOMNode_Release(node2);
9791
9792     /* release node before map release, map still works */
9793     IXMLDOMNode_Release(node);
9794
9795     length = 0;
9796     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9797     ok(hr == S_OK, "got %08x\n", hr);
9798     ok(length == 1, "got %d\n", length);
9799
9800     node2 = NULL;
9801     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9802     ok(hr == S_OK, "got %08x\n", hr);
9803     EXPECT_REF(node2, 1);
9804     IXMLDOMNode_Release(node2);
9805
9806     IXMLDOMNamedNodeMap_Release(map);
9807
9808     while (entry->type)
9809     {
9810         VARIANT var;
9811
9812         node = NULL;
9813
9814         V_VT(&var) = VT_I4;
9815         V_I4(&var) = entry->type;
9816         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9817         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9818
9819         hr = IXMLDOMNode_get_attributes(node, NULL);
9820         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9821
9822         map = (void*)0xdeadbeef;
9823         hr = IXMLDOMNode_get_attributes(node, &map);
9824         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9825             hr, entry->hr, entry->type);
9826         ok(map == NULL, "got %p\n", map);
9827
9828         IXMLDOMNode_Release(node);
9829
9830         entry++;
9831     }
9832
9833     IXMLDOMDocument_Release(doc);
9834     free_bstrs();
9835 }
9836
9837 static void test_selection(void)
9838 {
9839     IXMLDOMSelection *selection, *selection2;
9840     IEnumVARIANT *enum1, *enum2, *enum3;
9841     IXMLDOMNodeList *list;
9842     IXMLDOMDocument *doc;
9843     IDispatchEx *dispex;
9844     IXMLDOMNode *node;
9845     IDispatch *disp;
9846     VARIANT_BOOL b;
9847     HRESULT hr;
9848     DISPID did;
9849     VARIANT v;
9850     BSTR name;
9851     ULONG ret;
9852     LONG len;
9853
9854     doc = create_document(&IID_IXMLDOMDocument);
9855
9856     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
9857     EXPECT_HR(hr, S_OK);
9858
9859     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
9860     EXPECT_HR(hr, S_OK);
9861
9862     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9863     EXPECT_HR(hr, S_OK);
9864     IXMLDOMSelection_Release(selection);
9865
9866     /* collection disp id */
9867     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
9868     EXPECT_HR(hr, S_OK);
9869     did = 0;
9870     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
9871     EXPECT_HR(hr, S_OK);
9872     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
9873     len = 0;
9874     hr = IXMLDOMSelection_get_length(selection, &len);
9875     EXPECT_HR(hr, S_OK);
9876     ok(len == 1, "got %d\n", len);
9877     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
9878     EXPECT_HR(hr, S_OK);
9879     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
9880     IDispatchEx_Release(dispex);
9881
9882     /* IEnumVARIANT tests */
9883     enum1 = NULL;
9884     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
9885     EXPECT_HR(hr, S_OK);
9886     ok(enum1 != NULL, "got %p\n", enum1);
9887     EXPECT_REF(enum1, 2);
9888
9889     enum3 = NULL;
9890     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
9891     EXPECT_HR(hr, S_OK);
9892     ok(enum3 != NULL, "got %p\n", enum3);
9893     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
9894     EXPECT_REF(enum1, 3);
9895     IEnumVARIANT_Release(enum3);
9896
9897     EXPECT_REF(selection, 1);
9898     EXPECT_REF(enum1, 2);
9899
9900     enum2 = NULL;
9901     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9902     EXPECT_HR(hr, S_OK);
9903     ok(enum2 != NULL, "got %p\n", enum2);
9904
9905     EXPECT_REF(selection, 2);
9906     EXPECT_REF(enum1, 2);
9907     EXPECT_REF(enum2, 1);
9908
9909     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
9910
9911     selection2 = NULL;
9912     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
9913     EXPECT_HR(hr, S_OK);
9914     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
9915     EXPECT_REF(selection, 3);
9916     EXPECT_REF(enum1, 2);
9917
9918     IXMLDOMSelection_Release(selection2);
9919
9920     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
9921     EXPECT_HR(hr, S_OK);
9922     EXPECT_REF(selection, 3);
9923     IDispatch_Release(disp);
9924
9925     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
9926     EXPECT_HR(hr, S_OK);
9927     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
9928     EXPECT_REF(selection, 2);
9929     EXPECT_REF(enum1, 3);
9930
9931     IEnumVARIANT_Release(enum1);
9932     IEnumVARIANT_Release(enum2);
9933
9934     enum1 = NULL;
9935     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
9936     EXPECT_HR(hr, S_OK);
9937     ok(enum1 != NULL, "got %p\n", enum1);
9938     EXPECT_REF(enum1, 1);
9939     EXPECT_REF(selection, 2);
9940
9941     enum2 = NULL;
9942     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9943     EXPECT_HR(hr, S_OK);
9944     ok(enum2 != NULL, "got %p\n", enum2);
9945     EXPECT_REF(enum2, 1);
9946     EXPECT_REF(selection, 3);
9947
9948     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
9949
9950     IEnumVARIANT_AddRef(enum1);
9951     EXPECT_REF(selection, 3);
9952     EXPECT_REF(enum1, 2);
9953     EXPECT_REF(enum2, 1);
9954     IEnumVARIANT_Release(enum1);
9955
9956     IEnumVARIANT_Release(enum1);
9957     IEnumVARIANT_Release(enum2);
9958
9959     EXPECT_REF(selection, 1);
9960
9961     IXMLDOMNodeList_Release(list);
9962
9963     hr = IXMLDOMDocument_get_childNodes(doc, &list);
9964     EXPECT_HR(hr, S_OK);
9965
9966     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9967     EXPECT_HR(hr, E_NOINTERFACE);
9968
9969     IXMLDOMNodeList_Release(list);
9970
9971     /* test if IEnumVARIANT touches selection context */
9972     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
9973     EXPECT_HR(hr, S_OK);
9974
9975     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
9976     EXPECT_HR(hr, S_OK);
9977
9978     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9979     EXPECT_HR(hr, S_OK);
9980
9981     len = 0;
9982     hr = IXMLDOMSelection_get_length(selection, &len);
9983     EXPECT_HR(hr, S_OK);
9984     ok(len == 4, "got %d\n", len);
9985
9986     enum1 = NULL;
9987     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
9988     EXPECT_HR(hr, S_OK);
9989
9990     /* no-op if zero count */
9991     V_VT(&v) = VT_I2;
9992     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
9993     EXPECT_HR(hr, S_OK);
9994     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
9995
9996     /* positive count, null array pointer */
9997     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
9998     EXPECT_HR(hr, E_INVALIDARG);
9999
10000     ret = 1;
10001     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10002     EXPECT_HR(hr, E_INVALIDARG);
10003     ok(ret == 0, "got %d\n", ret);
10004
10005     V_VT(&v) = VT_I2;
10006     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10007     EXPECT_HR(hr, S_OK);
10008     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10009
10010     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10011     EXPECT_HR(hr, S_OK);
10012     hr = IXMLDOMNode_get_nodeName(node, &name);
10013     EXPECT_HR(hr, S_OK);
10014     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10015     SysFreeString(name);
10016     IXMLDOMNode_Release(node);
10017     VariantClear(&v);
10018
10019     /* list cursor is updated */
10020     hr = IXMLDOMSelection_nextNode(selection, &node);
10021     EXPECT_HR(hr, S_OK);
10022     hr = IXMLDOMNode_get_nodeName(node, &name);
10023     EXPECT_HR(hr, S_OK);
10024     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10025     IXMLDOMNode_Release(node);
10026
10027     V_VT(&v) = VT_I2;
10028     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10029     EXPECT_HR(hr, S_OK);
10030     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10031     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10032     EXPECT_HR(hr, S_OK);
10033     hr = IXMLDOMNode_get_nodeName(node, &name);
10034     EXPECT_HR(hr, S_OK);
10035     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10036     SysFreeString(name);
10037     IXMLDOMNode_Release(node);
10038     VariantClear(&v);
10039
10040     hr = IXMLDOMSelection_nextNode(selection, &node);
10041     EXPECT_HR(hr, S_OK);
10042     hr = IXMLDOMNode_get_nodeName(node, &name);
10043     EXPECT_HR(hr, S_OK);
10044     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10045     IXMLDOMNode_Release(node);
10046
10047     IXMLDOMSelection_Release(selection);
10048     IXMLDOMNodeList_Release(list);
10049     IXMLDOMDocument_Release(doc);
10050
10051     free_bstrs();
10052 }
10053
10054 static void test_load(void)
10055 {
10056     IXMLDOMDocument *doc;
10057     IXMLDOMNodeList *list;
10058     VARIANT_BOOL b;
10059     HANDLE hfile;
10060     VARIANT src;
10061     HRESULT hr;
10062     BOOL ret;
10063     BSTR path, bstr1, bstr2;
10064     DWORD written;
10065     void* ptr;
10066
10067     /* prepare a file */
10068     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10069     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10070     if(hfile == INVALID_HANDLE_VALUE) return;
10071
10072     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10073     ok(ret, "WriteFile failed\n");
10074
10075     CloseHandle(hfile);
10076
10077     doc = create_document(&IID_IXMLDOMDocument);
10078
10079     path = _bstr_("test.xml");
10080
10081     /* load from path: VT_BSTR */
10082     V_VT(&src) = VT_BSTR;
10083     V_BSTR(&src) = path;
10084     hr = IXMLDOMDocument_load(doc, src, &b);
10085     EXPECT_HR(hr, S_OK);
10086     ok(b == VARIANT_TRUE, "got %d\n", b);
10087
10088     /* load from a path: VT_BSTR|VT_BYREF */
10089     V_VT(&src) = VT_BSTR | VT_BYREF;
10090     V_BSTRREF(&src) = &path;
10091     hr = IXMLDOMDocument_load(doc, src, &b);
10092     EXPECT_HR(hr, S_OK);
10093     ok(b == VARIANT_TRUE, "got %d\n", b);
10094
10095     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10096     V_VT(&src) = VT_BSTR | VT_BYREF;
10097     V_BSTRREF(&src) = NULL;
10098     hr = IXMLDOMDocument_load(doc, src, &b);
10099     EXPECT_HR(hr, E_INVALIDARG);
10100     ok(b == VARIANT_FALSE, "got %d\n", b);
10101
10102     IXMLDOMDocument_Release(doc);
10103
10104     DeleteFileA("test.xml");
10105
10106     doc = create_document(&IID_IXMLDOMDocument);
10107
10108     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10109     EXPECT_HR(hr, S_OK);
10110     ok(b == VARIANT_TRUE, "got %d\n", b);
10111
10112     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10113     EXPECT_HR(hr, S_OK);
10114     bstr1 = _bstr_(list_to_string(list));
10115
10116     hr = IXMLDOMNodeList_reset(list);
10117     EXPECT_HR(hr, S_OK);
10118
10119     IXMLDOMDocument_Release(doc);
10120
10121     doc = create_document(&IID_IXMLDOMDocument);
10122
10123     VariantInit(&src);
10124     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10125     V_VT(&src) = VT_ARRAY|VT_UI1;
10126     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10127     ptr = NULL;
10128     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10129     EXPECT_HR(hr, S_OK);
10130     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10131
10132     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10133     hr = SafeArrayUnlock(V_ARRAY(&src));
10134     EXPECT_HR(hr, S_OK);
10135
10136     hr = IXMLDOMDocument_load(doc, src, &b);
10137     EXPECT_HR(hr, S_OK);
10138     ok(b == VARIANT_TRUE, "got %d\n", b);
10139
10140     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10141     EXPECT_HR(hr, S_OK);
10142     bstr2 = _bstr_(list_to_string(list));
10143
10144     hr = IXMLDOMNodeList_reset(list);
10145     EXPECT_HR(hr, S_OK);
10146
10147     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10148        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10149
10150     IXMLDOMDocument_Release(doc);
10151     IXMLDOMNodeList_Release(list);
10152     VariantClear(&src);
10153
10154     /* UTF-16 isn't accepted */
10155     doc = create_document(&IID_IXMLDOMDocument);
10156
10157     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10158     V_VT(&src) = VT_ARRAY|VT_UI1;
10159     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10160     ptr = NULL;
10161     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10162     EXPECT_HR(hr, S_OK);
10163     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10164
10165     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10166     hr = SafeArrayUnlock(V_ARRAY(&src));
10167     EXPECT_HR(hr, S_OK);
10168
10169     hr = IXMLDOMDocument_load(doc, src, &b);
10170     todo_wine EXPECT_HR(hr, S_FALSE);
10171     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10172
10173     VariantClear(&src);
10174
10175     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10176     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10177     V_VT(&src) = VT_ARRAY|VT_UI2;
10178     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10179     ptr = NULL;
10180     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10181     EXPECT_HR(hr, S_OK);
10182     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10183
10184     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10185     hr = SafeArrayUnlock(V_ARRAY(&src));
10186     EXPECT_HR(hr, S_OK);
10187
10188     hr = IXMLDOMDocument_load(doc, src, &b);
10189     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10190     ok(b == VARIANT_FALSE, "got %d\n", b);
10191
10192     VariantClear(&src);
10193     IXMLDOMDocument_Release(doc);
10194
10195     free_bstrs();
10196 }
10197
10198 static void test_nsnamespacemanager(void)
10199 {
10200     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10201     IMXNamespaceManager *nsmgr;
10202     IVBMXNamespaceManager *mgr2;
10203     IDispatch *disp;
10204     HRESULT hr;
10205     WCHAR buffW[250];
10206     INT len;
10207
10208     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10209         &IID_IMXNamespaceManager, (void**)&nsmgr);
10210     if (hr != S_OK)
10211     {
10212         win_skip("MXNamespaceManager is not available\n");
10213         return;
10214     }
10215
10216     /* IMXNamespaceManager inherits from IUnknown */
10217     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10218     EXPECT_HR(hr, S_OK);
10219     IDispatch_Release(disp);
10220
10221     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10222     EXPECT_HR(hr, S_OK);
10223     IVBMXNamespaceManager_Release(mgr2);
10224
10225     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10226     EXPECT_HR(hr, S_OK);
10227
10228     /* prefix already added */
10229     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10230     EXPECT_HR(hr, S_FALSE);
10231
10232     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10233     EXPECT_HR(hr, E_INVALIDARG);
10234
10235     /* "xml" and "xmlns" are not allowed here */
10236     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10237     EXPECT_HR(hr, E_INVALIDARG);
10238
10239     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10240     EXPECT_HR(hr, E_INVALIDARG);
10241 todo_wine {
10242     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10243     EXPECT_HR(hr, E_FAIL);
10244 }
10245     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10246     EXPECT_HR(hr, E_POINTER);
10247
10248     len = -1;
10249     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10250     EXPECT_HR(hr, S_OK);
10251     ok(len == 3, "got %d\n", len);
10252
10253     len = -1;
10254     buffW[0] = 0x1;
10255     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10256     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10257     ok(len == -1, "got %d\n", len);
10258     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10259
10260     len = 10;
10261     buffW[0] = 0x1;
10262     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10263     EXPECT_HR(hr, S_OK);
10264     ok(len == 3, "got %d\n", len);
10265     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10266
10267     /* getURI */
10268     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10269     EXPECT_HR(hr, E_INVALIDARG);
10270
10271     len = -1;
10272     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10273     EXPECT_HR(hr, E_INVALIDARG);
10274     ok(len == -1, "got %d\n", len);
10275
10276     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10277     EXPECT_HR(hr, E_POINTER);
10278
10279     len = -1;
10280     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10281     EXPECT_HR(hr, S_OK);
10282     /* length of "xml" uri is constant */
10283     ok(len == strlen(xmluriA), "got %d\n", len);
10284
10285     len = 100;
10286     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10287     EXPECT_HR(hr, S_OK);
10288     ok(len == strlen(xmluriA), "got %d\n", len);
10289     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10290
10291     len = strlen(xmluriA)-1;
10292     buffW[0] = 0x1;
10293     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10294     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10295     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10296     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10297
10298     /* prefix xml1 not defined */
10299     len = -1;
10300     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10301     EXPECT_HR(hr, S_FALSE);
10302     ok(len == 0, "got %d\n", len);
10303
10304     len = 100;
10305     buffW[0] = 0x1;
10306     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10307     EXPECT_HR(hr, S_FALSE);
10308     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10309     ok(len == 0, "got %d\n", len);
10310
10311     IMXNamespaceManager_Release(nsmgr);
10312
10313     free_bstrs();
10314 }
10315
10316 static void test_nsnamespacemanager_override(void)
10317 {
10318     IMXNamespaceManager *nsmgr;
10319     WCHAR buffW[250];
10320     VARIANT_BOOL b;
10321     HRESULT hr;
10322     INT len;
10323
10324     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10325         &IID_IMXNamespaceManager, (void**)&nsmgr);
10326     if (hr != S_OK)
10327     {
10328         win_skip("MXNamespaceManager is not available\n");
10329         return;
10330     }
10331
10332     len = sizeof(buffW)/sizeof(WCHAR);
10333     buffW[0] = 0;
10334     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10335     EXPECT_HR(hr, S_OK);
10336     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10337
10338     len = sizeof(buffW)/sizeof(WCHAR);
10339     buffW[0] = 0;
10340     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10341     EXPECT_HR(hr, E_FAIL);
10342
10343     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10344     EXPECT_HR(hr, E_POINTER);
10345
10346     b = VARIANT_FALSE;
10347     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10348     EXPECT_HR(hr, S_OK);
10349     ok(b == VARIANT_TRUE, "got %d\n", b);
10350
10351     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10352     EXPECT_HR(hr, S_OK);
10353
10354     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10355     EXPECT_HR(hr, S_OK);
10356
10357     len = sizeof(buffW)/sizeof(WCHAR);
10358     buffW[0] = 0;
10359     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10360     EXPECT_HR(hr, S_OK);
10361     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10362
10363     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10364     EXPECT_HR(hr, S_OK);
10365
10366     len = sizeof(buffW)/sizeof(WCHAR);
10367     buffW[0] = 0;
10368     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10369     EXPECT_HR(hr, S_OK);
10370     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10371
10372     len = sizeof(buffW)/sizeof(WCHAR);
10373     buffW[0] = 0;
10374     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10375     EXPECT_HR(hr, S_OK);
10376     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10377
10378     len = sizeof(buffW)/sizeof(WCHAR);
10379     buffW[0] = 0;
10380     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10381     EXPECT_HR(hr, S_OK);
10382     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10383
10384     /* new prefix placed at index 1 always */
10385     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10386     EXPECT_HR(hr, S_OK);
10387
10388     len = sizeof(buffW)/sizeof(WCHAR);
10389     buffW[0] = 0;
10390     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10391     EXPECT_HR(hr, S_OK);
10392     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10393
10394     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10395     todo_wine EXPECT_HR(hr, E_FAIL);
10396
10397     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10398     EXPECT_HR(hr, E_FAIL);
10399
10400     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10401     EXPECT_HR(hr, E_FAIL);
10402
10403     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10404     EXPECT_HR(hr, S_OK);
10405
10406     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10407     EXPECT_HR(hr, S_FALSE);
10408
10409     len = sizeof(buffW)/sizeof(WCHAR);
10410     buffW[0] = 0;
10411     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10412     EXPECT_HR(hr, S_OK);
10413     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10414
10415     len = sizeof(buffW)/sizeof(WCHAR);
10416     buffW[0] = 0;
10417     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10418     EXPECT_HR(hr, S_OK);
10419     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10420
10421     IMXNamespaceManager_Release(nsmgr);
10422
10423     free_bstrs();
10424 }
10425
10426 static void test_domobj_dispex(IUnknown *obj)
10427 {
10428     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10429     IDispatchEx *dispex;
10430     IUnknown *unk;
10431     DWORD props;
10432     UINT ticnt;
10433     HRESULT hr;
10434     BSTR name;
10435
10436     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10437     EXPECT_HR(hr, S_OK);
10438     if (FAILED(hr)) return;
10439
10440     ticnt = 0;
10441     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10442     EXPECT_HR(hr, S_OK);
10443     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10444
10445     name = SysAllocString(szstar);
10446     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10447     EXPECT_HR(hr, E_NOTIMPL);
10448     SysFreeString(name);
10449
10450     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10451     EXPECT_HR(hr, E_NOTIMPL);
10452
10453     props = 0;
10454     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10455     EXPECT_HR(hr, E_NOTIMPL);
10456     ok(props == 0, "expected 0 got %d\n", props);
10457
10458     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10459     EXPECT_HR(hr, E_NOTIMPL);
10460     if (SUCCEEDED(hr)) SysFreeString(name);
10461
10462     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10463     EXPECT_HR(hr, E_NOTIMPL);
10464
10465     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10466     EXPECT_HR(hr, E_NOTIMPL);
10467     if (hr == S_OK && unk) IUnknown_Release(unk);
10468
10469     IDispatchEx_Release(dispex);
10470 }
10471
10472 static const DOMNodeType dispex_types_test[] =
10473 {
10474     NODE_ELEMENT,
10475     NODE_ATTRIBUTE,
10476     NODE_TEXT,
10477     NODE_CDATA_SECTION,
10478     NODE_ENTITY_REFERENCE,
10479     NODE_PROCESSING_INSTRUCTION,
10480     NODE_COMMENT,
10481     NODE_DOCUMENT_FRAGMENT,
10482     NODE_INVALID
10483 };
10484
10485 static void test_dispex(void)
10486 {
10487     const DOMNodeType *type = dispex_types_test;
10488     IXMLDOMImplementation *impl;
10489     IXMLDOMNodeList *node_list;
10490     IXMLDOMParseError *error;
10491     IXMLDOMNamedNodeMap *map;
10492     IXMLDOMDocument *doc;
10493     IXMLHTTPRequest *req;
10494     IXMLDOMElement *elem;
10495     IDispatchEx *dispex;
10496     IXMLDOMNode *node;
10497     VARIANT_BOOL b;
10498     IUnknown *unk;
10499     HRESULT hr;
10500     DISPID did;
10501
10502     doc = create_document(&IID_IXMLDOMDocument);
10503
10504     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10505     test_domobj_dispex(unk);
10506     IUnknown_Release(unk);
10507
10508     for(; *type != NODE_INVALID; type++)
10509     {
10510         IXMLDOMNode *node;
10511         VARIANT v;
10512
10513         V_VT(&v) = VT_I2;
10514         V_I2(&v) = *type;
10515
10516         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10517         ok(hr == S_OK, "failed to create node type %d\n", *type);
10518
10519         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10520
10521         test_domobj_dispex(unk);
10522         IUnknown_Release(unk);
10523         IXMLDOMNode_Release(node);
10524     }
10525
10526     /* IXMLDOMNodeList */
10527     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10528     EXPECT_HR(hr, S_OK);
10529     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10530     test_domobj_dispex(unk);
10531     IUnknown_Release(unk);
10532     IXMLDOMNodeList_Release(node_list);
10533
10534     /* IXMLDOMParseError */
10535     hr = IXMLDOMDocument_get_parseError(doc, &error);
10536     EXPECT_HR(hr, S_OK);
10537     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
10538     test_domobj_dispex(unk);
10539     IUnknown_Release(unk);
10540     IXMLDOMParseError_Release(error);
10541
10542     /* IXMLDOMNamedNodeMap */
10543     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10544     EXPECT_HR(hr, S_OK);
10545
10546     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
10547     EXPECT_HR(hr, S_OK);
10548     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10549     EXPECT_HR(hr, S_OK);
10550     IXMLDOMNodeList_Release(node_list);
10551
10552     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10553     EXPECT_HR(hr, S_OK);
10554     IXMLDOMNode_Release(node);
10555     hr = IXMLDOMElement_get_attributes(elem, &map);
10556     EXPECT_HR(hr, S_OK);
10557     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
10558     test_domobj_dispex(unk);
10559     IUnknown_Release(unk);
10560     /* collection dispex test */
10561     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10562     EXPECT_HR(hr, S_OK);
10563     did = 0;
10564     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10565     EXPECT_HR(hr, S_OK);
10566     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10567     IDispatchEx_Release(dispex);
10568
10569     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
10570     EXPECT_HR(hr, S_OK);
10571     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10572     EXPECT_HR(hr, S_OK);
10573     IXMLDOMNodeList_Release(node_list);
10574     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10575     EXPECT_HR(hr, S_OK);
10576     IXMLDOMNode_Release(node);
10577     hr = IXMLDOMElement_get_attributes(elem, &map);
10578     EXPECT_HR(hr, S_OK);
10579     /* collection dispex test, empty collection */
10580     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10581     EXPECT_HR(hr, S_OK);
10582     did = 0;
10583     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10584     EXPECT_HR(hr, S_OK);
10585     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10586     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10587     EXPECT_HR(hr, S_OK);
10588     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10589     IDispatchEx_Release(dispex);
10590
10591     IXMLDOMNamedNodeMap_Release(map);
10592     IXMLDOMElement_Release(elem);
10593
10594     /* IXMLDOMImplementation */
10595     hr = IXMLDOMDocument_get_implementation(doc, &impl);
10596     EXPECT_HR(hr, S_OK);
10597
10598     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
10599     EXPECT_HR(hr, S_OK);
10600     IDispatchEx_Release(dispex);
10601     IXMLDOMImplementation_Release(impl);
10602
10603     IXMLDOMDocument_Release(doc);
10604
10605     /* IXMLHTTPRequest */
10606     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
10607         &IID_IXMLHttpRequest, (void**)&req);
10608     if (hr == S_OK)
10609     {
10610         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
10611         EXPECT_HR(hr, E_NOINTERFACE);
10612         IXMLHTTPRequest_Release(req);
10613     }
10614
10615     free_bstrs();
10616 }
10617
10618 static void test_parseerror(void)
10619 {
10620     IXMLDOMParseError *error;
10621     IXMLDOMDocument *doc;
10622     HRESULT hr;
10623
10624     doc = create_document(&IID_IXMLDOMDocument);
10625
10626     hr = IXMLDOMDocument_get_parseError(doc, &error);
10627     EXPECT_HR(hr, S_OK);
10628
10629     hr = IXMLDOMParseError_get_line(error, NULL);
10630     EXPECT_HR(hr, E_INVALIDARG);
10631
10632     hr = IXMLDOMParseError_get_srcText(error, NULL);
10633     EXPECT_HR(hr, E_INVALIDARG);
10634
10635     hr = IXMLDOMParseError_get_linepos(error, NULL);
10636     EXPECT_HR(hr, E_INVALIDARG);
10637
10638     IXMLDOMParseError_Release(error);
10639
10640     IXMLDOMDocument_Release(doc);
10641 }
10642
10643 static void test_getAttributeNode(void)
10644 {
10645     IXMLDOMAttribute *attr;
10646     IXMLDOMDocument *doc;
10647     IXMLDOMElement *elem;
10648     VARIANT_BOOL v;
10649     HRESULT hr;
10650     BSTR str;
10651
10652     doc = create_document(&IID_IXMLDOMDocument);
10653
10654     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
10655     EXPECT_HR(hr, S_OK);
10656
10657     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
10658     EXPECT_HR(hr, S_OK);
10659
10660     str = SysAllocString(nonexistent_fileW);
10661     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
10662     EXPECT_HR(hr, E_FAIL);
10663
10664     attr = (IXMLDOMAttribute*)0xdeadbeef;
10665     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
10666     EXPECT_HR(hr, E_FAIL);
10667     ok(attr == NULL, "got %p\n", attr);
10668     SysFreeString(str);
10669
10670     str = SysAllocString(nonexistent_attrW);
10671     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
10672     EXPECT_HR(hr, S_FALSE);
10673
10674     attr = (IXMLDOMAttribute*)0xdeadbeef;
10675     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
10676     EXPECT_HR(hr, S_FALSE);
10677     ok(attr == NULL, "got %p\n", attr);
10678     SysFreeString(str);
10679
10680     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
10681     EXPECT_HR(hr, S_OK);
10682     IXMLDOMAttribute_Release(attr);
10683
10684     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
10685     EXPECT_HR(hr, S_FALSE);
10686
10687     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
10688     EXPECT_HR(hr, S_OK);
10689     IXMLDOMAttribute_Release(attr);
10690
10691     IXMLDOMElement_Release(elem);
10692     IXMLDOMDocument_Release(doc);
10693     free_bstrs();
10694 }
10695
10696 typedef struct {
10697     DOMNodeType type;
10698     const char *name;
10699     REFIID iids[3];
10700 } supporterror_t;
10701
10702 static const supporterror_t supporterror_test[] = {
10703     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
10704     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
10705     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
10706     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
10707     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
10708     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
10709     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
10710     { NODE_INVALID }
10711 };
10712
10713 static void test_supporterrorinfo(void)
10714 {
10715     static REFIID iids[4] = { &IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
10716     const supporterror_t *ptr = supporterror_test;
10717     ISupportErrorInfo *errorinfo, *info2;
10718     IXMLDOMDocument *doc;
10719     IUnknown *unk;
10720     REFIID *iid;
10721     HRESULT hr;
10722
10723     doc = create_document_version(60, &IID_IXMLDOMDocument3);
10724     if (!doc) return;
10725
10726     EXPECT_REF(doc, 1);
10727     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
10728     EXPECT_HR(hr, S_OK);
10729     EXPECT_REF(doc, 1);
10730     ISupportErrorInfo_AddRef(errorinfo);
10731     EXPECT_REF(errorinfo, 2);
10732     EXPECT_REF(doc, 1);
10733     ISupportErrorInfo_Release(errorinfo);
10734
10735     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
10736     EXPECT_HR(hr, S_OK);
10737     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
10738     ISupportErrorInfo_Release(info2);
10739
10740     iid = iids;
10741     while (*iid)
10742     {
10743         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
10744         EXPECT_HR(hr, S_OK);
10745         if (hr == S_OK)
10746         {
10747             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
10748             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
10749             IUnknown_Release(unk);
10750         }
10751
10752         iid++;
10753     }
10754
10755     ISupportErrorInfo_Release(errorinfo);
10756
10757     while (ptr->type != NODE_INVALID)
10758     {
10759         IXMLDOMNode *node;
10760         VARIANT type;
10761
10762         V_VT(&type) = VT_I1;
10763         V_I1(&type) = ptr->type;
10764
10765         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
10766         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
10767
10768         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
10769         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
10770
10771         iid = ptr->iids;
10772
10773         while (*iid)
10774         {
10775             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
10776             if (hr == S_OK)
10777             {
10778                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
10779                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
10780                 IUnknown_Release(unk);
10781             }
10782
10783             iid++;
10784         }
10785
10786         ISupportErrorInfo_Release(errorinfo);
10787         IXMLDOMNode_Release(node);
10788         ptr++;
10789     }
10790
10791     IXMLDOMDocument_Release(doc);
10792     free_bstrs();
10793 }
10794
10795 START_TEST(domdoc)
10796 {
10797     IXMLDOMDocument *doc;
10798     HRESULT hr;
10799
10800     hr = CoInitialize( NULL );
10801     ok( hr == S_OK, "failed to init com\n");
10802     if (hr != S_OK) return;
10803
10804     test_XMLHTTP();
10805
10806     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
10807     if (hr != S_OK)
10808     {
10809         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
10810         return;
10811     }
10812
10813     IXMLDOMDocument_Release(doc);
10814
10815     test_domdoc();
10816     test_persiststreaminit();
10817     test_domnode();
10818     test_refs();
10819     test_create();
10820     test_getElementsByTagName();
10821     test_get_text();
10822     test_get_childNodes();
10823     test_get_firstChild();
10824     test_get_lastChild();
10825     test_removeChild();
10826     test_replaceChild();
10827     test_removeNamedItem();
10828     test_IXMLDOMDocument2();
10829     test_whitespace();
10830     test_XPath();
10831     test_XSLPattern();
10832     test_cloneNode();
10833     test_xmlTypes();
10834     test_nodeTypeTests();
10835     test_save();
10836     test_testTransforms();
10837     test_namespaces();
10838     test_FormattingXML();
10839     test_nodeTypedValue();
10840     test_TransformWithLoadingLocalFile();
10841     test_put_nodeValue();
10842     test_document_IObjectSafety();
10843     test_splitText();
10844     test_getQualifiedItem();
10845     test_removeQualifiedItem();
10846     test_get_ownerDocument();
10847     test_setAttributeNode();
10848     test_put_dataType();
10849     test_createNode();
10850     test_get_prefix();
10851     test_default_properties();
10852     test_selectSingleNode();
10853     test_events();
10854     test_createProcessingInstruction();
10855     test_put_nodeTypedValue();
10856     test_get_xml();
10857     test_insertBefore();
10858     test_appendChild();
10859     test_get_doctype();
10860     test_get_tagName();
10861     test_get_dataType();
10862     test_get_nodeTypeString();
10863     test_get_attributes();
10864     test_selection();
10865     test_load();
10866     test_dispex();
10867     test_parseerror();
10868     test_getAttributeNode();
10869     test_supporterrorinfo();
10870
10871     test_xsltemplate();
10872
10873     test_nsnamespacemanager();
10874     test_nsnamespacemanager_override();
10875
10876     CoUninitialize();
10877 }