msxml3: Implemented get_responseStream().
[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 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
47
48 #define DEFINE_EXPECT(func) \
49     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
50
51 #define SET_EXPECT(func) \
52     expect_ ## func = TRUE
53
54 #define CHECK_EXPECT2(func) \
55     do { \
56         ok(expect_ ##func, "unexpected call " #func "\n"); \
57         called_ ## func = TRUE; \
58     }while(0)
59
60 #define CHECK_CALLED(func) \
61     do { \
62         ok(called_ ## func, "expected " #func "\n"); \
63         expect_ ## func = called_ ## func = FALSE; \
64     }while(0)
65
66 static const char *debugstr_guid(REFIID riid)
67 {
68     static char buf[50];
69
70     if(!riid)
71         return "(null)";
72
73     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
74             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
75             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
76             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
77
78     return buf;
79 }
80
81 static int g_unexpectedcall, g_expectedcall;
82
83 typedef struct
84 {
85     IDispatch IDispatch_iface;
86     LONG ref;
87 } dispevent;
88
89 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
90 {
91     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
92 }
93
94 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
95 {
96     *ppvObject = NULL;
97
98     if ( IsEqualGUID( riid, &IID_IDispatch) ||
99          IsEqualGUID( riid, &IID_IUnknown) )
100     {
101         *ppvObject = iface;
102     }
103     else
104         return E_NOINTERFACE;
105
106     IDispatch_AddRef( iface );
107
108     return S_OK;
109 }
110
111 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
112 {
113     dispevent *This = impl_from_IDispatch( iface );
114     return InterlockedIncrement( &This->ref );
115 }
116
117 static ULONG WINAPI dispevent_Release(IDispatch *iface)
118 {
119     dispevent *This = impl_from_IDispatch( iface );
120     ULONG ref = InterlockedDecrement( &This->ref );
121
122     if (ref == 0)
123         HeapFree(GetProcessHeap(), 0, This);
124
125     return ref;
126 }
127
128 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
129 {
130     g_unexpectedcall++;
131     *pctinfo = 0;
132     return S_OK;
133 }
134
135 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
136         LCID lcid, ITypeInfo **ppTInfo)
137 {
138     g_unexpectedcall++;
139     return S_OK;
140 }
141
142 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
143         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
144 {
145     g_unexpectedcall++;
146     return S_OK;
147 }
148
149 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
150         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
151         EXCEPINFO *excepInfo, UINT *argErr)
152 {
153     ok(member == 0, "expected 0 member, got %d\n", member);
154     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
155     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
156
157     ok(params->cArgs == 0, "got %d\n", params->cArgs);
158     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
159     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
160     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
161
162     ok(result == NULL, "got %p\n", result);
163     ok(excepInfo == NULL, "got %p\n", excepInfo);
164     ok(argErr == NULL, "got %p\n", argErr);
165
166     g_expectedcall++;
167     return E_FAIL;
168 }
169
170 static const IDispatchVtbl dispeventVtbl =
171 {
172     dispevent_QueryInterface,
173     dispevent_AddRef,
174     dispevent_Release,
175     dispevent_GetTypeInfoCount,
176     dispevent_GetTypeInfo,
177     dispevent_GetIDsOfNames,
178     dispevent_Invoke
179 };
180
181 static IDispatch* create_dispevent(void)
182 {
183     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
184
185     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
186     event->ref = 1;
187
188     return (IDispatch*)&event->IDispatch_iface;
189 }
190
191 /* object site */
192 DEFINE_EXPECT(site_qi_IServiceProvider);
193 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
194 DEFINE_EXPECT(site_qi_IOleClientSite);
195
196 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
197 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
198 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
199 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
200 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
201
202 DEFINE_EXPECT(htmldoc2_get_all);
203 DEFINE_EXPECT(htmldoc2_get_url);
204 DEFINE_EXPECT(collection_get_length);
205
206 typedef struct
207 {
208     IServiceProvider IServiceProvider_iface;
209 } testprov_t;
210
211 testprov_t testprov;
212
213 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
214 {
215     *ppvObject = NULL;
216
217     if (IsEqualGUID(riid, &IID_IServiceProvider))
218         CHECK_EXPECT2(site_qi_IServiceProvider);
219
220     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
221         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
222
223     if (IsEqualGUID(riid, &IID_IOleClientSite))
224         CHECK_EXPECT2(site_qi_IOleClientSite);
225
226     if (IsEqualGUID(riid, &IID_IUnknown))
227          *ppvObject = iface;
228     else if (IsEqualGUID(riid, &IID_IServiceProvider))
229          *ppvObject = &testprov.IServiceProvider_iface;
230
231     if (*ppvObject) IUnknown_AddRef(iface);
232
233     return *ppvObject ? S_OK : E_NOINTERFACE;
234 }
235
236 static ULONG WINAPI site_AddRef(IUnknown *iface)
237 {
238     return 2;
239 }
240
241 static ULONG WINAPI site_Release(IUnknown *iface)
242 {
243     return 1;
244 }
245
246 static const IUnknownVtbl testsiteVtbl =
247 {
248     site_QueryInterface,
249     site_AddRef,
250     site_Release
251 };
252
253 typedef struct
254 {
255     IUnknown IUnknown_iface;
256 } testsite_t;
257
258 static testsite_t testsite = { { &testsiteVtbl } };
259
260 /* test IHTMLElementCollection */
261 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
262 {
263     ok(0, "unexpected call\n");
264     *ppvObject = NULL;
265     return E_NOINTERFACE;
266 }
267
268 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
269 {
270     return 2;
271 }
272
273 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
274 {
275     return 1;
276 }
277
278 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
279 {
280     ok(0, "unexpected call\n");
281     return E_NOTIMPL;
282 }
283
284 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
285                                                 LCID lcid, ITypeInfo **ppTInfo)
286 {
287     ok(0, "unexpected call\n");
288     return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
292                                                 LPOLESTR *rgszNames, UINT cNames,
293                                                 LCID lcid, DISPID *rgDispId)
294 {
295     ok(0, "unexpected call\n");
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
300                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
301                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
302 {
303     ok(0, "unexpected call\n");
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
308 {
309     ok(0, "unexpected call\n");
310     return E_NOTIMPL;
311 }
312
313 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
314 {
315     ok(0, "unexpected call\n");
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
320 {
321     CHECK_EXPECT2(collection_get_length);
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
332 {
333     ok(0, "unexpected call\n");
334     return E_NOTIMPL;
335 }
336
337 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
338 {
339     ok(0, "unexpected call\n");
340     return E_NOTIMPL;
341 }
342
343 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
344     htmlecoll_QueryInterface,
345     htmlecoll_AddRef,
346     htmlecoll_Release,
347     htmlecoll_GetTypeInfoCount,
348     htmlecoll_GetTypeInfo,
349     htmlecoll_GetIDsOfNames,
350     htmlecoll_Invoke,
351
352     htmlecoll_toString,
353     htmlecoll_put_length,
354     htmlecoll_get_length,
355     htmlecoll_get__newEnum,
356     htmlecoll_item,
357     htmlecoll_tags
358 };
359
360 typedef struct
361 {
362     IHTMLElementCollection IHTMLElementCollection_iface;
363 } testhtmlecoll_t;
364
365 static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
366
367 /* test IHTMLDocument2 */
368 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
369 {
370    trace("\n");
371    *ppvObject = NULL;
372    return E_NOINTERFACE;
373 }
374
375 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
376 {
377     return 2;
378 }
379
380 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
381 {
382     return 1;
383 }
384
385 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
386 {
387     ok(0, "unexpected call\n");
388     return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
392                                                 LCID lcid, ITypeInfo **ppTInfo)
393 {
394     ok(0, "unexpected call\n");
395     return E_NOTIMPL;
396 }
397
398 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
399                                                 LPOLESTR *rgszNames, UINT cNames,
400                                                 LCID lcid, DISPID *rgDispId)
401 {
402     ok(0, "unexpected call\n");
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
407                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
408                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
409 {
410     ok(0, "unexpected call\n");
411     return E_NOTIMPL;
412 }
413
414 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
415 {
416     ok(0, "unexpected call\n");
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
421 {
422     CHECK_EXPECT2(htmldoc2_get_all);
423     *p = &htmlecoll.IHTMLElementCollection_iface;
424     return S_OK;
425 }
426
427 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
428 {
429     ok(0, "unexpected call\n");
430     return E_NOTIMPL;
431 }
432
433 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
434 {
435     ok(0, "unexpected call\n");
436     return E_NOTIMPL;
437 }
438
439 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
440 {
441     ok(0, "unexpected call\n");
442     return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
446 {
447     ok(0, "unexpected call\n");
448     return E_NOTIMPL;
449 }
450
451 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
452 {
453     ok(0, "unexpected call\n");
454     return E_NOTIMPL;
455 }
456
457 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
458 {
459     ok(0, "unexpected call\n");
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
464 {
465     ok(0, "unexpected call\n");
466     return E_NOTIMPL;
467 }
468
469 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
470 {
471     ok(0, "unexpected call\n");
472     return E_NOTIMPL;
473 }
474
475 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
476 {
477     ok(0, "unexpected call\n");
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
482 {
483     ok(0, "unexpected call\n");
484     return E_NOTIMPL;
485 }
486
487 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
488 {
489     ok(0, "unexpected call\n");
490     return E_NOTIMPL;
491 }
492
493 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
494 {
495     ok(0, "unexpected call\n");
496     return E_NOTIMPL;
497 }
498
499 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
500 {
501     ok(0, "unexpected call\n");
502     return E_NOTIMPL;
503 }
504
505 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
506 {
507     ok(0, "unexpected call\n");
508     return E_NOTIMPL;
509 }
510
511 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
512 {
513     ok(0, "unexpected call\n");
514     return E_NOTIMPL;
515 }
516
517 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
518 {
519     ok(0, "unexpected call\n");
520     return E_NOTIMPL;
521 }
522
523 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
524 {
525     ok(0, "unexpected call\n");
526     return E_NOTIMPL;
527 }
528
529 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
530 {
531     ok(0, "unexpected call\n");
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
536 {
537     ok(0, "unexpected call\n");
538     return E_NOTIMPL;
539 }
540
541 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
542 {
543     ok(0, "unexpected call\n");
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
548 {
549     ok(0, "unexpected call\n");
550     return E_NOTIMPL;
551 }
552
553 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
554 {
555     ok(0, "unexpected call\n");
556     return E_NOTIMPL;
557 }
558
559 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
560 {
561     ok(0, "unexpected call\n");
562     return E_NOTIMPL;
563 }
564
565 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
566 {
567     ok(0, "unexpected call\n");
568     return E_NOTIMPL;
569 }
570
571 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
572 {
573     ok(0, "unexpected call\n");
574     return E_NOTIMPL;
575 }
576
577 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
578 {
579     ok(0, "unexpected call\n");
580     return E_NOTIMPL;
581 }
582
583 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
584 {
585     ok(0, "unexpected call\n");
586     return E_NOTIMPL;
587 }
588
589 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
590 {
591     ok(0, "unexpected call\n");
592     return E_NOTIMPL;
593 }
594
595 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
596 {
597     ok(0, "unexpected call\n");
598     return E_NOTIMPL;
599 }
600
601 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
602 {
603     ok(0, "unexpected call\n");
604     return E_NOTIMPL;
605 }
606
607 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
608 {
609     ok(0, "unexpected call\n");
610     return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
614 {
615     CHECK_EXPECT2(htmldoc2_get_url);
616     *p = SysAllocString(NULL);
617     return S_OK;
618 }
619
620 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
621 {
622     ok(0, "unexpected call\n");
623     return E_NOTIMPL;
624 }
625
626 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
627 {
628     ok(0, "unexpected call\n");
629     return E_NOTIMPL;
630 }
631
632 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
633 {
634     ok(0, "unexpected call\n");
635     return E_NOTIMPL;
636 }
637
638 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
639 {
640     ok(0, "unexpected call\n");
641     return E_NOTIMPL;
642 }
643
644 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
645 {
646     ok(0, "unexpected call\n");
647     return E_NOTIMPL;
648 }
649
650 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
651 {
652     ok(0, "unexpected call\n");
653     return E_NOTIMPL;
654 }
655
656 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
657 {
658     ok(0, "unexpected call\n");
659     return E_NOTIMPL;
660 }
661
662 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
663 {
664     ok(0, "unexpected call\n");
665     return E_NOTIMPL;
666 }
667
668 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
669 {
670     ok(0, "unexpected call\n");
671     return E_NOTIMPL;
672 }
673
674 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
675 {
676     ok(0, "unexpected call\n");
677     return E_NOTIMPL;
678 }
679
680 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
681 {
682     ok(0, "unexpected call\n");
683     return E_NOTIMPL;
684 }
685
686 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
687 {
688     ok(0, "unexpected call\n");
689     return E_NOTIMPL;
690 }
691
692 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
693 {
694     ok(0, "unexpected call\n");
695     return E_NOTIMPL;
696 }
697
698 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
699 {
700     ok(0, "unexpected call\n");
701     return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
705 {
706     ok(0, "unexpected call\n");
707     return E_NOTIMPL;
708 }
709
710 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
711 {
712     ok(0, "unexpected call\n");
713     return E_NOTIMPL;
714 }
715
716 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
717 {
718     ok(0, "unexpected call\n");
719     return E_NOTIMPL;
720 }
721
722 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
723 {
724     ok(0, "unexpected call\n");
725     return E_NOTIMPL;
726 }
727
728 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
729 {
730     ok(0, "unexpected call\n");
731     return E_NOTIMPL;
732 }
733
734 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
735 {
736     ok(0, "unexpected call\n");
737     return E_NOTIMPL;
738 }
739
740 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
741                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
742 {
743     ok(0, "unexpected call\n");
744     return E_NOTIMPL;
745 }
746
747 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
748 {
749     ok(0, "unexpected call\n");
750     return E_NOTIMPL;
751 }
752
753 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
754 {
755     ok(0, "unexpected call\n");
756     return E_NOTIMPL;
757 }
758
759 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
760                                                         VARIANT_BOOL *pfRet)
761 {
762     ok(0, "unexpected call\n");
763     return E_NOTIMPL;
764 }
765
766 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
767                                                         VARIANT_BOOL *pfRet)
768 {
769     ok(0, "unexpected call\n");
770     return E_NOTIMPL;
771 }
772
773 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
774                                                         VARIANT_BOOL *pfRet)
775 {
776     ok(0, "unexpected call\n");
777     return E_NOTIMPL;
778 }
779
780 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
781                                                         VARIANT_BOOL *pfRet)
782 {
783     ok(0, "unexpected call\n");
784     return E_NOTIMPL;
785 }
786
787 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
788                                                         BSTR *pfRet)
789 {
790     ok(0, "unexpected call\n");
791     return E_NOTIMPL;
792 }
793
794 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
795                                                         VARIANT *pfRet)
796 {
797     ok(0, "unexpected call\n");
798     return E_NOTIMPL;
799 }
800
801 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
802                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
803 {
804     ok(0, "unexpected call\n");
805     return E_NOTIMPL;
806 }
807
808 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
809                                                         VARIANT_BOOL *pfRet)
810 {
811     ok(0, "unexpected call\n");
812     return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
816                                                  IHTMLElement **newElem)
817 {
818     ok(0, "unexpected call\n");
819     return E_NOTIMPL;
820 }
821
822 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
823 {
824     ok(0, "unexpected call\n");
825     return E_NOTIMPL;
826 }
827
828 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
829 {
830     ok(0, "unexpected call\n");
831     return E_NOTIMPL;
832 }
833
834 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
835 {
836     ok(0, "unexpected call\n");
837     return E_NOTIMPL;
838 }
839
840 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
841 {
842     ok(0, "unexpected call\n");
843     return E_NOTIMPL;
844 }
845
846 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
847 {
848     ok(0, "unexpected call\n");
849     return E_NOTIMPL;
850 }
851
852 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
853 {
854     ok(0, "unexpected call\n");
855     return E_NOTIMPL;
856 }
857
858 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
859 {
860     ok(0, "unexpected call\n");
861     return E_NOTIMPL;
862 }
863
864 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
865 {
866     ok(0, "unexpected call\n");
867     return E_NOTIMPL;
868 }
869
870 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
871 {
872     ok(0, "unexpected call\n");
873     return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
877 {
878     ok(0, "unexpected call\n");
879     return E_NOTIMPL;
880 }
881
882 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
883 {
884     ok(0, "unexpected call\n");
885     return E_NOTIMPL;
886 }
887
888 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
889 {
890     ok(0, "unexpected call\n");
891     return E_NOTIMPL;
892 }
893
894 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
895 {
896     ok(0, "unexpected call\n");
897     return E_NOTIMPL;
898 }
899
900 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
901 {
902     ok(0, "unexpected call\n");
903     return E_NOTIMPL;
904 }
905
906 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
907 {
908     ok(0, "unexpected call\n");
909     return E_NOTIMPL;
910 }
911
912 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
913 {
914     ok(0, "unexpected call\n");
915     return E_NOTIMPL;
916 }
917
918 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
919 {
920     ok(0, "unexpected call\n");
921     return E_NOTIMPL;
922 }
923
924 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
925 {
926     ok(0, "unexpected call\n");
927     return E_NOTIMPL;
928 }
929
930 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
931 {
932     ok(0, "unexpected call\n");
933     return E_NOTIMPL;
934 }
935
936 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
937 {
938     ok(0, "unexpected call\n");
939     return E_NOTIMPL;
940 }
941
942 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
943 {
944     ok(0, "unexpected call\n");
945     return E_NOTIMPL;
946 }
947
948 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
949 {
950     ok(0, "unexpected call\n");
951     return E_NOTIMPL;
952 }
953
954 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
955 {
956     ok(0, "unexpected call\n");
957     return E_NOTIMPL;
958 }
959
960 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
961 {
962     ok(0, "unexpected call\n");
963     return E_NOTIMPL;
964 }
965
966 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
967 {
968     ok(0, "unexpected call\n");
969     return E_NOTIMPL;
970 }
971
972 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
973 {
974     ok(0, "unexpected call\n");
975     return E_NOTIMPL;
976 }
977
978 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
979 {
980     ok(0, "unexpected call\n");
981     return E_NOTIMPL;
982 }
983
984 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
985 {
986     ok(0, "unexpected call\n");
987     return E_NOTIMPL;
988 }
989
990 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
991 {
992     ok(0, "unexpected call\n");
993     return E_NOTIMPL;
994 }
995
996 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
997 {
998     ok(0, "unexpected call\n");
999     return E_NOTIMPL;
1000 }
1001
1002 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1003 {
1004     ok(0, "unexpected call\n");
1005     return E_NOTIMPL;
1006 }
1007
1008 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1009 {
1010     ok(0, "unexpected call\n");
1011     return E_NOTIMPL;
1012 }
1013
1014 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1015 {
1016     ok(0, "unexpected call\n");
1017     return E_NOTIMPL;
1018 }
1019
1020 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1021 {
1022     ok(0, "unexpected call\n");
1023     return E_NOTIMPL;
1024 }
1025
1026 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1027                                                         IHTMLElement **elementHit)
1028 {
1029     ok(0, "unexpected call\n");
1030     return E_NOTIMPL;
1031 }
1032
1033 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1034 {
1035     ok(0, "unexpected call\n");
1036     return E_NOTIMPL;
1037 }
1038
1039 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
1040                                                    IHTMLStyleSheetsCollection **p)
1041 {
1042     ok(0, "unexpected call\n");
1043     return E_NOTIMPL;
1044 }
1045
1046 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1047 {
1048     ok(0, "unexpected call\n");
1049     return E_NOTIMPL;
1050 }
1051
1052 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1053 {
1054     ok(0, "unexpected call\n");
1055     return E_NOTIMPL;
1056 }
1057
1058 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1059 {
1060     ok(0, "unexpected call\n");
1061     return E_NOTIMPL;
1062 }
1063
1064 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1065 {
1066     ok(0, "unexpected call\n");
1067     return E_NOTIMPL;
1068 }
1069
1070 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
1071 {
1072     ok(0, "unexpected call\n");
1073     return E_NOTIMPL;
1074 }
1075
1076 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1077                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1078 {
1079     ok(0, "unexpected call\n");
1080     return E_NOTIMPL;
1081 }
1082
1083 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
1084     htmldoc2_QueryInterface,
1085     htmldoc2_AddRef,
1086     htmldoc2_Release,
1087     htmldoc2_GetTypeInfoCount,
1088     htmldoc2_GetTypeInfo,
1089     htmldoc2_GetIDsOfNames,
1090     htmldoc2_Invoke,
1091     htmldoc2_get_Script,
1092     htmldoc2_get_all,
1093     htmldoc2_get_body,
1094     htmldoc2_get_activeElement,
1095     htmldoc2_get_images,
1096     htmldoc2_get_applets,
1097     htmldoc2_get_links,
1098     htmldoc2_get_forms,
1099     htmldoc2_get_anchors,
1100     htmldoc2_put_title,
1101     htmldoc2_get_title,
1102     htmldoc2_get_scripts,
1103     htmldoc2_put_designMode,
1104     htmldoc2_get_designMode,
1105     htmldoc2_get_selection,
1106     htmldoc2_get_readyState,
1107     htmldoc2_get_frames,
1108     htmldoc2_get_embeds,
1109     htmldoc2_get_plugins,
1110     htmldoc2_put_alinkColor,
1111     htmldoc2_get_alinkColor,
1112     htmldoc2_put_bgColor,
1113     htmldoc2_get_bgColor,
1114     htmldoc2_put_fgColor,
1115     htmldoc2_get_fgColor,
1116     htmldoc2_put_linkColor,
1117     htmldoc2_get_linkColor,
1118     htmldoc2_put_vlinkColor,
1119     htmldoc2_get_vlinkColor,
1120     htmldoc2_get_referrer,
1121     htmldoc2_get_location,
1122     htmldoc2_get_lastModified,
1123     htmldoc2_put_URL,
1124     htmldoc2_get_URL,
1125     htmldoc2_put_domain,
1126     htmldoc2_get_domain,
1127     htmldoc2_put_cookie,
1128     htmldoc2_get_cookie,
1129     htmldoc2_put_expando,
1130     htmldoc2_get_expando,
1131     htmldoc2_put_charset,
1132     htmldoc2_get_charset,
1133     htmldoc2_put_defaultCharset,
1134     htmldoc2_get_defaultCharset,
1135     htmldoc2_get_mimeType,
1136     htmldoc2_get_fileSize,
1137     htmldoc2_get_fileCreatedDate,
1138     htmldoc2_get_fileModifiedDate,
1139     htmldoc2_get_fileUpdatedDate,
1140     htmldoc2_get_security,
1141     htmldoc2_get_protocol,
1142     htmldoc2_get_nameProp,
1143     htmldoc2_write,
1144     htmldoc2_writeln,
1145     htmldoc2_open,
1146     htmldoc2_close,
1147     htmldoc2_clear,
1148     htmldoc2_queryCommandSupported,
1149     htmldoc2_queryCommandEnabled,
1150     htmldoc2_queryCommandState,
1151     htmldoc2_queryCommandIndeterm,
1152     htmldoc2_queryCommandText,
1153     htmldoc2_queryCommandValue,
1154     htmldoc2_execCommand,
1155     htmldoc2_execCommandShowHelp,
1156     htmldoc2_createElement,
1157     htmldoc2_put_onhelp,
1158     htmldoc2_get_onhelp,
1159     htmldoc2_put_onclick,
1160     htmldoc2_get_onclick,
1161     htmldoc2_put_ondblclick,
1162     htmldoc2_get_ondblclick,
1163     htmldoc2_put_onkeyup,
1164     htmldoc2_get_onkeyup,
1165     htmldoc2_put_onkeydown,
1166     htmldoc2_get_onkeydown,
1167     htmldoc2_put_onkeypress,
1168     htmldoc2_get_onkeypress,
1169     htmldoc2_put_onmouseup,
1170     htmldoc2_get_onmouseup,
1171     htmldoc2_put_onmousedown,
1172     htmldoc2_get_onmousedown,
1173     htmldoc2_put_onmousemove,
1174     htmldoc2_get_onmousemove,
1175     htmldoc2_put_onmouseout,
1176     htmldoc2_get_onmouseout,
1177     htmldoc2_put_onmouseover,
1178     htmldoc2_get_onmouseover,
1179     htmldoc2_put_onreadystatechange,
1180     htmldoc2_get_onreadystatechange,
1181     htmldoc2_put_onafterupdate,
1182     htmldoc2_get_onafterupdate,
1183     htmldoc2_put_onrowexit,
1184     htmldoc2_get_onrowexit,
1185     htmldoc2_put_onrowenter,
1186     htmldoc2_get_onrowenter,
1187     htmldoc2_put_ondragstart,
1188     htmldoc2_get_ondragstart,
1189     htmldoc2_put_onselectstart,
1190     htmldoc2_get_onselectstart,
1191     htmldoc2_elementFromPoint,
1192     htmldoc2_get_parentWindow,
1193     htmldoc2_get_styleSheets,
1194     htmldoc2_put_onbeforeupdate,
1195     htmldoc2_get_onbeforeupdate,
1196     htmldoc2_put_onerrorupdate,
1197     htmldoc2_get_onerrorupdate,
1198     htmldoc2_toString,
1199     htmldoc2_createStyleSheet
1200 };
1201
1202 typedef struct
1203 {
1204     IHTMLDocument2 IHTMLDocument2_iface;
1205 } testhtmldoc2_t;
1206
1207 static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
1208
1209 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1210 {
1211     *ppvObject = NULL;
1212
1213     if (IsEqualGUID(riid, &IID_IUnknown) ||
1214         IsEqualGUID(riid, &IID_IServiceProvider))
1215     {
1216         *ppvObject = iface;
1217         IServiceProvider_AddRef(iface);
1218         return S_OK;
1219     }
1220
1221     ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
1222
1223     return E_NOINTERFACE;
1224 }
1225
1226 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1227 {
1228     return 2;
1229 }
1230
1231 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1232 {
1233     return 1;
1234 }
1235
1236 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1237 {
1238     *obj = NULL;
1239
1240     if (IsEqualGUID(service, &SID_SBindHost) &&
1241         IsEqualGUID(riid, &IID_IBindHost))
1242     {
1243         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1244     }
1245     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1246              IsEqualGUID(riid, &IID_IHTMLDocument2))
1247     {
1248         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1249     }
1250     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1251              IsEqualGUID(riid, &IID_IHTMLDocument2))
1252     {
1253         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1254         *obj = &htmldoc2.IHTMLDocument2_iface;
1255         return S_OK;
1256     }
1257     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1258              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1259     {
1260         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1261     }
1262     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1263              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1264     {
1265         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1266     }
1267     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1268              IsEqualGUID(riid, &IID_IStream))
1269     {
1270         /* FIXME: unidentified service id */
1271     }
1272     else
1273         ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
1274
1275     return E_NOTIMPL;
1276 }
1277
1278 static const IServiceProviderVtbl testprovVtbl =
1279 {
1280     sp_QueryInterface,
1281     sp_AddRef,
1282     sp_Release,
1283     sp_QueryService
1284 };
1285
1286 testprov_t testprov = { { &testprovVtbl } };
1287
1288 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1289 static void _expect_children(IXMLDOMNode *node, int line)
1290 {
1291     VARIANT_BOOL b;
1292     HRESULT hr;
1293
1294     b = VARIANT_FALSE;
1295     hr = IXMLDOMNode_hasChildNodes(node, &b);
1296     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1297     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1298 }
1299
1300 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1301 static void _expect_no_children(IXMLDOMNode *node, int line)
1302 {
1303     VARIANT_BOOL b;
1304     HRESULT hr;
1305
1306     b = VARIANT_TRUE;
1307     hr = IXMLDOMNode_hasChildNodes(node, &b);
1308     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1309     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1310 }
1311
1312 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1313 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1314 {
1315     ULONG rc = IUnknown_AddRef(obj);
1316     IUnknown_Release(obj);
1317     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1318 }
1319
1320 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1321 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1322 {
1323     LONG length;
1324     HRESULT hr;
1325
1326     length = 0;
1327     hr = IXMLDOMNodeList_get_length(list, &length);
1328     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1329     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1330 }
1331
1332 #define EXPECT_HR(hr,hr_exp) \
1333     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1334
1335 static const WCHAR szEmpty[] = { 0 };
1336 static const WCHAR szIncomplete[] = {
1337     '<','?','x','m','l',' ',
1338     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1339 };
1340 static const WCHAR szComplete1[] = {
1341     '<','?','x','m','l',' ',
1342     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1343     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1344 };
1345 static const WCHAR szComplete2[] = {
1346     '<','?','x','m','l',' ',
1347     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1348     '<','o','>','<','/','o','>','\n',0
1349 };
1350 static const WCHAR szComplete3[] = {
1351     '<','?','x','m','l',' ',
1352     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1353     '<','a','>','<','/','a','>','\n',0
1354 };
1355 static const char complete4A[] =
1356     "<?xml version=\'1.0\'?>\n"
1357     "<lc dl=\'str1\'>\n"
1358         "<bs vr=\'str2\' sz=\'1234\'>"
1359             "fn1.txt\n"
1360         "</bs>\n"
1361         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1362             "fn2.txt\n"
1363         "</pr>\n"
1364         "<empty></empty>\n"
1365         "<fo>\n"
1366             "<ba>\n"
1367                 "f1\n"
1368             "</ba>\n"
1369         "</fo>\n"
1370     "</lc>\n";
1371
1372 static const WCHAR szComplete5[] = {
1373     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1374     'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
1375     ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
1376         '<','S',':','s','c','o','p','e','>',
1377             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1378         '<','/','S',':','s','c','o','p','e','>',
1379         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1380             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1381             'c','o','m','p','u','t','e','r',
1382         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1383     '<','/','S',':','s','e','a','r','c','h','>',0
1384 };
1385
1386 static const WCHAR szComplete6[] = {
1387     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1388     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1389     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1390 };
1391
1392 static const CHAR szNonUnicodeXML[] =
1393 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1394 "<open></open>\n";
1395
1396 static const char szExampleXML[] =
1397 "<?xml version='1.0' encoding='utf-8'?>\n"
1398 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1399 "    <elem>\n"
1400 "        <a>A1 field</a>\n"
1401 "        <b>B1 field</b>\n"
1402 "        <c>C1 field</c>\n"
1403 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1404 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1405 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1406 "            </html>\n"
1407 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1408 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1409 "            </html>\n"
1410 "        </description>\n"
1411 "    </elem>\n"
1412 "\n"
1413 "    <elem>\n"
1414 "        <a>A2 field</a>\n"
1415 "        <b>B2 field</b>\n"
1416 "        <c type=\"old\">C2 field</c>\n"
1417 "    </elem>\n"
1418 "\n"
1419 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1420 "        <a>A3 field</a>\n"
1421 "        <b>B3 field</b>\n"
1422 "        <c>C3 field</c>\n"
1423 "    </elem>\n"
1424 "\n"
1425 "    <elem>\n"
1426 "        <a>A4 field</a>\n"
1427 "        <b>B4 field</b>\n"
1428 "        <foo:c>C4 field</foo:c>\n"
1429 "    </elem>\n"
1430 "</root>\n";
1431
1432 static const CHAR szNodeTypesXML[] =
1433 "<?xml version='1.0'?>"
1434 "<!-- comment node 0 -->"
1435 "<root id='0' depth='0'>"
1436 "   <!-- comment node 1 -->"
1437 "   text node 0"
1438 "   <x id='1' depth='1'>"
1439 "       <?foo value='PI for x'?>"
1440 "       <!-- comment node 2 -->"
1441 "       text node 1"
1442 "       <a id='3' depth='2'/>"
1443 "       <b id='4' depth='2'/>"
1444 "       <c id='5' depth='2'/>"
1445 "   </x>"
1446 "   <y id='2' depth='1'>"
1447 "       <?bar value='PI for y'?>"
1448 "       <!-- comment node 3 -->"
1449 "       text node 2"
1450 "       <a id='6' depth='2'/>"
1451 "       <b id='7' depth='2'/>"
1452 "       <c id='8' depth='2'/>"
1453 "   </y>"
1454 "</root>";
1455
1456 static const CHAR szTransformXML[] =
1457 "<?xml version=\"1.0\"?>\n"
1458 "<greeting>\n"
1459 "Hello World\n"
1460 "</greeting>";
1461
1462 static  const CHAR szTransformSSXML[] =
1463 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1464 "   <xsl:output method=\"html\"/>\n"
1465 "   <xsl:template match=\"/\">\n"
1466 "       <xsl:apply-templates select=\"greeting\"/>\n"
1467 "   </xsl:template>\n"
1468 "   <xsl:template match=\"greeting\">\n"
1469 "       <html>\n"
1470 "           <body>\n"
1471 "               <h1>\n"
1472 "                   <xsl:value-of select=\".\"/>\n"
1473 "               </h1>\n"
1474 "           </body>\n"
1475 "       </html>\n"
1476 "   </xsl:template>\n"
1477 "</xsl:stylesheet>";
1478
1479 static  const CHAR szTransformOutput[] =
1480 "<html><body><h1>"
1481 "Hello World"
1482 "</h1></body></html>";
1483
1484 static const CHAR szTypeValueXML[] =
1485 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1486 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1487 "   <string>Wine</string>\n"
1488 "   <string2 dt:dt=\"string\">String</string2>\n"
1489 "   <number dt:dt=\"number\">12.44</number>\n"
1490 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1491 "   <int dt:dt=\"int\">-13</int>\n"
1492 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1493 "   <bool dt:dt=\"boolean\">1</bool>\n"
1494 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1495 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1496 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1497 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1498 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1499 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1500 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1501 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1502 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1503 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1504 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1505 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1506 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1507 "   <float dt:dt=\"float\">41221.421</float>\n"
1508 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1509 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1510 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1511 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1512 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1513 "</root>";
1514
1515 static const CHAR szBasicTransformSSXMLPart1[] =
1516 "<?xml version=\"1.0\"?>"
1517 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1518 "<xsl:output method=\"html\"/>\n"
1519 "<xsl:template match=\"/\">"
1520 "<HTML><BODY><TABLE>"
1521 "        <xsl:apply-templates select='document(\"";
1522
1523 static const CHAR szBasicTransformSSXMLPart2[] =
1524 "\")/bottle/wine'>"
1525 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1526 "        </xsl:apply-templates>"
1527 "</TABLE></BODY></HTML>"
1528 "</xsl:template>"
1529 "<xsl:template match=\"bottle\">"
1530 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1531 "</xsl:template>"
1532 "<xsl:template match=\"name\">"
1533 "   <TD><xsl:apply-templates /></TD>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"cost\">"
1536 "   <TD><xsl:apply-templates /></TD>"
1537 "</xsl:template>"
1538 "</xsl:stylesheet>";
1539
1540 static const CHAR szBasicTransformXML[] =
1541 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1542
1543 static const CHAR szBasicTransformOutput[] =
1544 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1545
1546 #define SZ_EMAIL_DTD \
1547 "<!DOCTYPE email ["\
1548 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1549 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1550 "       <!ATTLIST email sent (yes|no) \"no\">"\
1551 "   <!ELEMENT recipients    (to+,cc*)>"\
1552 "   <!ELEMENT to            (#PCDATA)>"\
1553 "       <!ATTLIST to name CDATA #IMPLIED>"\
1554 "   <!ELEMENT cc            (#PCDATA)>"\
1555 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1556 "   <!ELEMENT from          (#PCDATA)>"\
1557 "       <!ATTLIST from name CDATA #IMPLIED>"\
1558 "   <!ELEMENT reply-to      (#PCDATA)>"\
1559 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1560 "   <!ELEMENT subject       ANY>"\
1561 "   <!ELEMENT body          ANY>"\
1562 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1563 "   <!ELEMENT attachment    (#PCDATA)>"\
1564 "       <!ATTLIST attachment id ID #REQUIRED>"\
1565 "]>"
1566
1567 static const CHAR szEmailXML[] =
1568 "<?xml version=\"1.0\"?>"
1569 SZ_EMAIL_DTD
1570 "<email attachments=\"patch1\">"
1571 "   <recipients>"
1572 "       <to>wine-patches@winehq.org</to>"
1573 "   </recipients>"
1574 "   <from name=\"Anonymous\">user@localhost</from>"
1575 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1576 "   <body>"
1577 "       It no longer causes spontaneous combustion..."
1578 "   </body>"
1579 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1580 "</email>";
1581
1582 static const CHAR szEmailXML_0D[] =
1583 "<?xml version=\"1.0\"?>"
1584 SZ_EMAIL_DTD
1585 "<email attachments=\"patch1\">"
1586 "   <recipients>"
1587 "       <to>wine-patches@winehq.org</to>"
1588 "   </recipients>"
1589 "   <from name=\"Anonymous\">user@localhost</from>"
1590 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1591 "   <body>"
1592 "       <undecl />"
1593 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1594 "   </body>"
1595 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1596 "</email>";
1597
1598 static const CHAR szEmailXML_0E[] =
1599 "<?xml version=\"1.0\"?>"
1600 SZ_EMAIL_DTD
1601 "<email attachments=\"patch1\">"
1602 "   <recipients>"
1603 "       <to>wine-patches@winehq.org</to>"
1604 "   </recipients>"
1605 "   <from name=\"Anonymous\">user@localhost</from>"
1606 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1607 "   <body>"
1608 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1609 "   </body>"
1610 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1611 "</email>";
1612
1613 static const CHAR szEmailXML_11[] =
1614 "<?xml version=\"1.0\"?>"
1615 SZ_EMAIL_DTD
1616 "<email attachments=\"patch1\">"
1617 "   <recipients>"
1618 "   </recipients>"
1619 "   <from name=\"Anonymous\">user@localhost</from>"
1620 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1621 "   <body>"
1622 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1623 "   </body>"
1624 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1625 "</email>";
1626
1627 static const CHAR szEmailXML_13[] =
1628 "<?xml version=\"1.0\"?>"
1629 SZ_EMAIL_DTD
1630 "<msg attachments=\"patch1\">"
1631 "   <recipients>"
1632 "       <to>wine-patches@winehq.org</to>"
1633 "   </recipients>"
1634 "   <from name=\"Anonymous\">user@localhost</from>"
1635 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1636 "   <body>"
1637 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1638 "   </body>"
1639 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1640 "</msg>";
1641
1642 static const CHAR szEmailXML_14[] =
1643 "<?xml version=\"1.0\"?>"
1644 SZ_EMAIL_DTD
1645 "<email attachments=\"patch1\">"
1646 "   <to>wine-patches@winehq.org</to>"
1647 "   <from name=\"Anonymous\">user@localhost</from>"
1648 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1649 "   <body>"
1650 "       XML_INVALID_CONTENT 0xC00CE014"
1651 "   </body>"
1652 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1653 "</email>";
1654
1655 static const CHAR szEmailXML_15[] =
1656 "<?xml version=\"1.0\"?>"
1657 SZ_EMAIL_DTD
1658 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1659 "   <recipients>"
1660 "       <to>wine-patches@winehq.org</to>"
1661 "   </recipients>"
1662 "   <from name=\"Anonymous\">user@localhost</from>"
1663 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1664 "   <body>"
1665 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1666 "   </body>"
1667 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1668 "</email>";
1669
1670 static const CHAR szEmailXML_16[] =
1671 "<?xml version=\"1.0\"?>"
1672 SZ_EMAIL_DTD
1673 "<email attachments=\"patch1\">"
1674 "   <recipients>"
1675 "       <to>wine-patches@winehq.org</to>"
1676 "   </recipients>"
1677 "   <from name=\"Anonymous\">user@localhost</from>"
1678 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1679 "   <body enc=\"ASCII\">"
1680 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1681 "   </body>"
1682 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1683 "</email>";
1684
1685 static const CHAR szEmailXML_17[] =
1686 "<?xml version=\"1.0\"?>"
1687 SZ_EMAIL_DTD
1688 "<email attachments=\"patch1\" sent=\"true\">"
1689 "   <recipients>"
1690 "       <to>wine-patches@winehq.org</to>"
1691 "   </recipients>"
1692 "   <from name=\"Anonymous\">user@localhost</from>"
1693 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1694 "   <body>"
1695 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1696 "   </body>"
1697 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1698 "</email>";
1699
1700 static const CHAR szEmailXML_18[] =
1701 "<?xml version=\"1.0\"?>"
1702 SZ_EMAIL_DTD
1703 "<email attachments=\"patch1\">"
1704 "   oops"
1705 "   <recipients>"
1706 "       <to>wine-patches@winehq.org</to>"
1707 "   </recipients>"
1708 "   <from name=\"Anonymous\">user@localhost</from>"
1709 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1710 "   <body>"
1711 "       XML_ILLEGAL_TEXT 0xC00CE018"
1712 "   </body>"
1713 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1714 "</email>";
1715
1716 static const CHAR szEmailXML_20[] =
1717 "<?xml version=\"1.0\"?>"
1718 SZ_EMAIL_DTD
1719 "<email>"
1720 "   <recipients>"
1721 "       <to>wine-patches@winehq.org</to>"
1722 "   </recipients>"
1723 "   <from name=\"Anonymous\">user@localhost</from>"
1724 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1725 "   <body>"
1726 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1727 "   </body>"
1728 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1729 "</email>";
1730
1731 static const char xpath_simple_list[] =
1732 "<?xml version=\"1.0\"?>"
1733 "<root>"
1734 "   <a attr1=\"1\" attr2=\"2\" />"
1735 "   <b/>"
1736 "   <c/>"
1737 "   <d/>"
1738 "</root>";
1739
1740 static const char* leading_spaces[] = {
1741     "\n<?xml version=\"1.0\"?><root/>",
1742     " <?xml version=\"1.0\"?><root/>",
1743     "\t<?xml version=\"1.0\"?><root/>",
1744     "\r\n<?xml version=\"1.0\"?><root/>",
1745     "\r<?xml version=\"1.0\"?><root/>",
1746     0
1747 };
1748
1749 static const char default_ns_doc[] = {
1750     "<?xml version=\"1.0\"?>"
1751     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1752     "    d=\"d attr\" />"
1753 };
1754
1755 static const WCHAR nonexistent_fileW[] = {
1756     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1757 };
1758 static const WCHAR nonexistent_attrW[] = {
1759     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1760 };
1761 static const WCHAR szDocument[] = {
1762     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1763 };
1764
1765 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1766 static WCHAR szdl[] = { 'd','l',0 };
1767 static const WCHAR szvr[] = { 'v','r',0 };
1768 static const WCHAR szlc[] = { 'l','c',0 };
1769 static WCHAR szbs[] = { 'b','s',0 };
1770 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1771 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1772 static const WCHAR szstar[] = { '*',0 };
1773 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1774
1775 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1776 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1777 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1778
1779 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1780 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1781 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1782 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1783                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1784 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1785                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1786
1787 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1788 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1789
1790 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1791                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1792 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1793                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1794                              '!',']',']','>',0};
1795 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1796 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1797
1798 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1799 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1800 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1801
1802 #define expect_bstr_eq_and_free(bstr, expect) { \
1803     BSTR bstrExp = alloc_str_from_narrow(expect); \
1804     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1805     SysFreeString(bstr); \
1806     SysFreeString(bstrExp); \
1807 }
1808
1809 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1810
1811 #define ole_check(expr) { \
1812     HRESULT r = expr; \
1813     ok(r == S_OK, #expr " returned %x\n", r); \
1814 }
1815
1816 #define ole_expect(expr, expect) { \
1817     HRESULT r = expr; \
1818     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1819 }
1820
1821 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1822
1823 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1824 {
1825     void *obj = NULL;
1826     HRESULT hr;
1827
1828     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1829     if (hr != S_OK)
1830         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1831
1832     return obj;
1833 }
1834
1835 #define _create(cls) cls, #cls
1836
1837 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
1838 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1839 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1840 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1841 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1842
1843 static BSTR alloc_str_from_narrow(const char *str)
1844 {
1845     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1846     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1847     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1848     return ret;
1849 }
1850
1851 static BSTR alloced_bstrs[256];
1852 static int alloced_bstrs_count;
1853
1854 static BSTR _bstr_(const char *str)
1855 {
1856     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1857     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1858     return alloced_bstrs[alloced_bstrs_count++];
1859 }
1860
1861 static void free_bstrs(void)
1862 {
1863     int i;
1864     for (i = 0; i < alloced_bstrs_count; i++)
1865         SysFreeString(alloced_bstrs[i]);
1866     alloced_bstrs_count = 0;
1867 }
1868
1869 static VARIANT _variantbstr_(const char *str)
1870 {
1871     VARIANT v;
1872     V_VT(&v) = VT_BSTR;
1873     V_BSTR(&v) = _bstr_(str);
1874     return v;
1875 }
1876
1877 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1878 {
1879     for (;;)
1880     {
1881         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1882         while (*sRight == '\r' || *sRight == '\n') sRight++;
1883         if (*sLeft != *sRight) return FALSE;
1884         if (!*sLeft) return TRUE;
1885         sLeft++;
1886         sRight++;
1887     }
1888 }
1889
1890 static void get_str_for_type(DOMNodeType type, char *buf)
1891 {
1892     switch (type)
1893     {
1894         case NODE_ATTRIBUTE:
1895             strcpy(buf, "A");
1896             break;
1897         case NODE_ELEMENT:
1898             strcpy(buf, "E");
1899             break;
1900         case NODE_DOCUMENT:
1901             strcpy(buf, "D");
1902             break;
1903         case NODE_TEXT:
1904             strcpy(buf, "T");
1905             break;
1906         case NODE_COMMENT:
1907             strcpy(buf, "C");
1908             break;
1909         case NODE_PROCESSING_INSTRUCTION:
1910             strcpy(buf, "P");
1911             break;
1912         default:
1913             wsprintfA(buf, "[%d]", type);
1914     }
1915 }
1916
1917 static int get_node_position(IXMLDOMNode *node)
1918 {
1919     HRESULT r;
1920     int pos = 0;
1921
1922     IXMLDOMNode_AddRef(node);
1923     do
1924     {
1925         IXMLDOMNode *new_node;
1926
1927         pos++;
1928         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1929         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1930         IXMLDOMNode_Release(node);
1931         node = new_node;
1932     } while (r == S_OK);
1933     return pos;
1934 }
1935
1936 static void node_to_string(IXMLDOMNode *node, char *buf)
1937 {
1938     HRESULT r = S_OK;
1939     DOMNodeType type;
1940
1941     if (node == NULL)
1942     {
1943         lstrcpyA(buf, "(null)");
1944         return;
1945     }
1946
1947     IXMLDOMNode_AddRef(node);
1948     while (r == S_OK)
1949     {
1950         IXMLDOMNode *new_node;
1951
1952         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1953         get_str_for_type(type, buf);
1954         buf+=strlen(buf);
1955
1956         if (type == NODE_ATTRIBUTE)
1957         {
1958             BSTR bstr;
1959             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1960             *(buf++) = '\'';
1961             wsprintfA(buf, "%ws", bstr);
1962             buf += strlen(buf);
1963             *(buf++) = '\'';
1964             SysFreeString(bstr);
1965
1966             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1967         }
1968         else
1969         {
1970             r = IXMLDOMNode_get_parentNode(node, &new_node);
1971             wsprintf(buf, "%d", get_node_position(node));
1972             buf += strlen(buf);
1973         }
1974
1975         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1976         IXMLDOMNode_Release(node);
1977         node = new_node;
1978         if (r == S_OK)
1979             *(buf++) = '.';
1980     }
1981
1982     *buf = 0;
1983 }
1984
1985 static char *list_to_string(IXMLDOMNodeList *list)
1986 {
1987     static char buf[4096];
1988     char *pos = buf;
1989     LONG len = 0;
1990     int i;
1991
1992     if (list == NULL)
1993     {
1994         lstrcpyA(buf, "(null)");
1995         return buf;
1996     }
1997     ole_check(IXMLDOMNodeList_get_length(list, &len));
1998     for (i = 0; i < len; i++)
1999     {
2000         IXMLDOMNode *node;
2001         if (i > 0)
2002             *(pos++) = ' ';
2003         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2004         node_to_string(node, pos);
2005         pos += strlen(pos);
2006         IXMLDOMNode_Release(node);
2007     }
2008     *pos = 0;
2009     return buf;
2010 }
2011
2012 #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); }
2013 #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); }
2014
2015 static void test_domdoc( void )
2016 {
2017     HRESULT r, hr;
2018     IXMLDOMDocument *doc;
2019     IXMLDOMParseError *error;
2020     IXMLDOMElement *element = NULL;
2021     IXMLDOMNode *node;
2022     IXMLDOMText *nodetext = NULL;
2023     IXMLDOMComment *node_comment = NULL;
2024     IXMLDOMAttribute *node_attr = NULL;
2025     IXMLDOMNode *nodeChild = NULL;
2026     IXMLDOMProcessingInstruction *nodePI = NULL;
2027     VARIANT_BOOL b;
2028     VARIANT var;
2029     BSTR str;
2030     LONG code, ref;
2031     LONG nLength = 0;
2032     WCHAR buff[100];
2033     const char **ptr;
2034
2035     doc = create_document(&IID_IXMLDOMDocument);
2036     if (!doc) return;
2037
2038 if (0)
2039 {
2040     /* crashes on native */
2041     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2042 }
2043
2044     /* try some stupid things */
2045     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2046     EXPECT_HR(hr, S_FALSE);
2047
2048     b = VARIANT_TRUE;
2049     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2050     EXPECT_HR(hr, S_FALSE);
2051     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2052
2053     /* load document with leading spaces */
2054     ptr = leading_spaces;
2055     while (*ptr)
2056     {
2057         b = VARIANT_TRUE;
2058         V_VT(&var) = VT_BSTR;
2059         V_BSTR(&var) = _bstr_(*ptr);
2060         hr = IXMLDOMDocument_load( doc, var, &b);
2061         EXPECT_HR(hr, S_FALSE);
2062         ok( b == VARIANT_FALSE, "got %x\n", b);
2063         ptr++;
2064     }
2065
2066     /* try to load a document from a nonexistent file */
2067     b = VARIANT_TRUE;
2068     str = SysAllocString( nonexistent_fileW );
2069     VariantInit(&var);
2070     V_VT(&var) = VT_BSTR;
2071     V_BSTR(&var) = str;
2072
2073     r = IXMLDOMDocument_load( doc, var, &b);
2074     ok( r == S_FALSE, "loadXML succeeded\n");
2075     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2076     SysFreeString( str );
2077
2078     /* try load an empty document */
2079     b = VARIANT_TRUE;
2080     str = SysAllocString( szEmpty );
2081     r = IXMLDOMDocument_loadXML( doc, str, &b );
2082     ok( r == S_FALSE, "loadXML succeeded\n");
2083     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2084     SysFreeString( str );
2085
2086     r = IXMLDOMDocument_get_async( doc, &b );
2087     ok( r == S_OK, "get_async failed (%08x)\n", r);
2088     ok( b == VARIANT_TRUE, "Wrong default value\n");
2089
2090     /* check that there's no document element */
2091     element = NULL;
2092     r = IXMLDOMDocument_get_documentElement( doc, &element );
2093     ok( r == S_FALSE, "should be no document element\n");
2094
2095     /* try finding a node */
2096     node = NULL;
2097     str = SysAllocString( szstr1 );
2098     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2099     ok( r == S_FALSE, "ret %08x\n", r );
2100     SysFreeString( str );
2101
2102     b = VARIANT_TRUE;
2103     str = SysAllocString( szIncomplete );
2104     r = IXMLDOMDocument_loadXML( doc, str, &b );
2105     ok( r == S_FALSE, "loadXML succeeded\n");
2106     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2107     SysFreeString( str );
2108
2109     /* check that there's no document element */
2110     element = (IXMLDOMElement*)1;
2111     r = IXMLDOMDocument_get_documentElement( doc, &element );
2112     ok( r == S_FALSE, "should be no document element\n");
2113     ok( element == NULL, "Element should be NULL\n");
2114
2115     /* test for BSTR handling, pass broken BSTR */
2116     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2117     /* just a big length */
2118     *(DWORD*)buff = 0xf0f0;
2119     b = VARIANT_FALSE;
2120     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2121     ok( r == S_OK, "loadXML failed\n");
2122     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2123
2124     /* loadXML ignores the encoding attribute and always expects Unicode */
2125     b = VARIANT_FALSE;
2126     str = SysAllocString( szComplete6 );
2127     r = IXMLDOMDocument_loadXML( doc, str, &b );
2128     ok( r == S_OK, "loadXML failed\n");
2129     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2130     SysFreeString( str );
2131
2132     /* try a BSTR containing a Windows-1252 document */
2133     b = VARIANT_TRUE;
2134     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2135     r = IXMLDOMDocument_loadXML( doc, str, &b );
2136     ok( r == S_FALSE, "loadXML succeeded\n");
2137     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2138     SysFreeString( str );
2139
2140     /* try to load something valid */
2141     b = VARIANT_FALSE;
2142     str = SysAllocString( szComplete1 );
2143     r = IXMLDOMDocument_loadXML( doc, str, &b );
2144     ok( r == S_OK, "loadXML failed\n");
2145     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2146     SysFreeString( str );
2147
2148     /* check if nodename is correct */
2149     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2150     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2151
2152     str = (BSTR)0xdeadbeef;
2153     r = IXMLDOMDocument_get_baseName( doc, &str );
2154     ok ( r == S_FALSE, "got 0x%08x\n", r);
2155     ok (str == NULL, "got %p\n", str);
2156
2157     /* content doesn't matter here */
2158     str = NULL;
2159     r = IXMLDOMDocument_get_nodeName( doc, &str );
2160     ok ( r == S_OK, "get_nodeName wrong code\n");
2161     ok ( str != NULL, "str is null\n");
2162     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2163     SysFreeString( str );
2164
2165     /* test put_text */
2166     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2167     ok( r == E_FAIL, "ret %08x\n", r );
2168
2169     /* check that there's a document element */
2170     element = NULL;
2171     r = IXMLDOMDocument_get_documentElement( doc, &element );
2172     ok( r == S_OK, "should be a document element\n");
2173     if( element )
2174     {
2175         IObjectIdentity *ident;
2176
2177         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2178         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2179
2180         IXMLDOMElement_Release( element );
2181         element = NULL;
2182     }
2183
2184     /* as soon as we call loadXML again, the document element will disappear */
2185     b = 2;
2186     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2187     ok( r == S_FALSE, "loadXML failed\n");
2188     ok( b == 2, "variant modified\n");
2189     r = IXMLDOMDocument_get_documentElement( doc, &element );
2190     ok( r == S_FALSE, "should be no document element\n");
2191
2192     /* try to load something else simple and valid */
2193     b = VARIANT_FALSE;
2194     str = SysAllocString( szComplete3 );
2195     r = IXMLDOMDocument_loadXML( doc, str, &b );
2196     ok( r == S_OK, "loadXML failed\n");
2197     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2198     SysFreeString( str );
2199
2200     /* try something a little more complicated */
2201     b = FALSE;
2202     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2203     ok( r == S_OK, "loadXML failed\n");
2204     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2205
2206     r = IXMLDOMDocument_get_parseError( doc, &error );
2207     ok( r == S_OK, "returns %08x\n", r );
2208
2209     r = IXMLDOMParseError_get_errorCode( error, &code );
2210     ok( r == S_FALSE, "returns %08x\n", r );
2211     ok( code == 0, "code %d\n", code );
2212     IXMLDOMParseError_Release( error );
2213
2214     /* test createTextNode */
2215     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2216     ok( r == S_OK, "returns %08x\n", r );
2217     IXMLDOMText_Release(nodetext);
2218
2219     str = SysAllocString( szOpen );
2220     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2221     ok( r == E_INVALIDARG, "returns %08x\n", r );
2222     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2223     ok( r == S_OK, "returns %08x\n", r );
2224     SysFreeString( str );
2225     if(nodetext)
2226     {
2227         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2228         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2229
2230         /* Text Last Child Checks */
2231         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2232         ok(r == E_INVALIDARG, "ret %08x\n", r );
2233
2234         nodeChild = (IXMLDOMNode*)0x1;
2235         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2236         ok(r == S_FALSE, "ret %08x\n", r );
2237         ok(nodeChild == NULL, "nodeChild not NULL\n");
2238
2239         /* test length property */
2240         r = IXMLDOMText_get_length(nodetext, NULL);
2241         ok(r == E_INVALIDARG, "ret %08x\n", r );
2242
2243         r = IXMLDOMText_get_length(nodetext, &nLength);
2244         ok(r == S_OK, "ret %08x\n", r );
2245         ok(nLength == 4, "expected 4 got %d\n", nLength);
2246
2247         /* put data Tests */
2248         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2249         ok(r == S_OK, "ret %08x\n", r );
2250
2251         /* get data Tests */
2252         r = IXMLDOMText_get_data(nodetext, &str);
2253         ok(r == S_OK, "ret %08x\n", r );
2254         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2255         SysFreeString(str);
2256
2257         /* Confirm XML text is good */
2258         r = IXMLDOMText_get_xml(nodetext, &str);
2259         ok(r == S_OK, "ret %08x\n", r );
2260         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2261         SysFreeString(str);
2262
2263         /* Confirm we get the put_data Text back */
2264         r = IXMLDOMText_get_text(nodetext, &str);
2265         ok(r == S_OK, "ret %08x\n", r );
2266         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2267         SysFreeString(str);
2268
2269         /* test substringData */
2270         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2271         ok(r == E_INVALIDARG, "ret %08x\n", r );
2272
2273         /* test substringData - Invalid offset */
2274         str = (BSTR)&szElement;
2275         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2276         ok(r == E_INVALIDARG, "ret %08x\n", r );
2277         ok( str == NULL, "incorrect string\n");
2278
2279         /* test substringData - Invalid offset */
2280         str = (BSTR)&szElement;
2281         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2282         ok(r == S_FALSE, "ret %08x\n", r );
2283         ok( str == NULL, "incorrect string\n");
2284
2285         /* test substringData - Invalid size */
2286         str = (BSTR)&szElement;
2287         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2288         ok(r == E_INVALIDARG, "ret %08x\n", r );
2289         ok( str == NULL, "incorrect string\n");
2290
2291         /* test substringData - Invalid size */
2292         str = (BSTR)&szElement;
2293         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2294         ok(r == S_FALSE, "ret %08x\n", r );
2295         ok( str == NULL, "incorrect string\n");
2296
2297         /* test substringData - Start of string */
2298         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2299         ok(r == S_OK, "ret %08x\n", r );
2300         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2301         SysFreeString(str);
2302
2303         /* test substringData - Middle of string */
2304         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2305         ok(r == S_OK, "ret %08x\n", r );
2306         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2307         SysFreeString(str);
2308
2309         /* test substringData - End of string */
2310         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2311         ok(r == S_OK, "ret %08x\n", r );
2312         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2313         SysFreeString(str);
2314
2315         /* test appendData */
2316         r = IXMLDOMText_appendData(nodetext, NULL);
2317         ok(r == S_OK, "ret %08x\n", r );
2318
2319         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2320         ok(r == S_OK, "ret %08x\n", r );
2321
2322         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2323         ok(r == S_OK, "ret %08x\n", r );
2324
2325         r = IXMLDOMText_get_text(nodetext, &str);
2326         ok(r == S_OK, "ret %08x\n", r );
2327         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2328         SysFreeString(str);
2329
2330         /* test insertData */
2331         str = SysAllocStringLen(NULL, 0);
2332         r = IXMLDOMText_insertData(nodetext, -1, str);
2333         ok(r == S_OK, "ret %08x\n", r );
2334
2335         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2336         ok(r == S_OK, "ret %08x\n", r );
2337
2338         r = IXMLDOMText_insertData(nodetext, 1000, str);
2339         ok(r == S_OK, "ret %08x\n", r );
2340
2341         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2342         ok(r == S_OK, "ret %08x\n", r );
2343
2344         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2345         ok(r == S_OK, "ret %08x\n", r );
2346
2347         r = IXMLDOMText_insertData(nodetext, 0, str);
2348         ok(r == S_OK, "ret %08x\n", r );
2349         SysFreeString(str);
2350
2351         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2352         ok(r == E_INVALIDARG, "ret %08x\n", r );
2353
2354         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2355         ok(r == E_INVALIDARG, "ret %08x\n", r );
2356
2357         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2358         ok(r == S_OK, "ret %08x\n", r );
2359
2360         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2361         ok(r == S_OK, "ret %08x\n", r );
2362
2363         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2364         ok(r == S_OK, "ret %08x\n", r );
2365
2366         r = IXMLDOMText_get_text(nodetext, &str);
2367         ok(r == S_OK, "ret %08x\n", r );
2368         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2369         SysFreeString(str);
2370
2371         /* delete data */
2372         /* invalid arguments */
2373         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2374         ok(r == E_INVALIDARG, "ret %08x\n", r );
2375
2376         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2377         ok(r == S_OK, "ret %08x\n", r );
2378
2379         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2380         ok(r == E_INVALIDARG, "ret %08x\n", r );
2381
2382         r = IXMLDOMText_get_length(nodetext, &nLength);
2383         ok(r == S_OK, "ret %08x\n", r );
2384         ok(nLength == 43, "expected 43 got %d\n", nLength);
2385
2386         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2387         ok(r == S_OK, "ret %08x\n", r );
2388
2389         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2390         ok(r == E_INVALIDARG, "ret %08x\n", r );
2391
2392         /* delete from start */
2393         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2394         ok(r == S_OK, "ret %08x\n", r );
2395
2396         r = IXMLDOMText_get_length(nodetext, &nLength);
2397         ok(r == S_OK, "ret %08x\n", r );
2398         ok(nLength == 38, "expected 38 got %d\n", nLength);
2399
2400         r = IXMLDOMText_get_text(nodetext, &str);
2401         ok(r == S_OK, "ret %08x\n", r );
2402         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2403         SysFreeString(str);
2404
2405         /* delete from end */
2406         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2407         ok(r == S_OK, "ret %08x\n", r );
2408
2409         r = IXMLDOMText_get_length(nodetext, &nLength);
2410         ok(r == S_OK, "ret %08x\n", r );
2411         ok(nLength == 35, "expected 35 got %d\n", nLength);
2412
2413         r = IXMLDOMText_get_text(nodetext, &str);
2414         ok(r == S_OK, "ret %08x\n", r );
2415         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2416         SysFreeString(str);
2417
2418         /* delete from inside */
2419         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2420         ok(r == S_OK, "ret %08x\n", r );
2421
2422         r = IXMLDOMText_get_length(nodetext, &nLength);
2423         ok(r == S_OK, "ret %08x\n", r );
2424         ok(nLength == 2, "expected 2 got %d\n", nLength);
2425
2426         r = IXMLDOMText_get_text(nodetext, &str);
2427         ok(r == S_OK, "ret %08x\n", r );
2428         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2429         SysFreeString(str);
2430
2431         /* delete whole data ... */
2432         r = IXMLDOMText_get_length(nodetext, &nLength);
2433         ok(r == S_OK, "ret %08x\n", r );
2434
2435         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2436         ok(r == S_OK, "ret %08x\n", r );
2437         /* ... and try again with empty string */
2438         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2439         ok(r == S_OK, "ret %08x\n", r );
2440
2441         /* test put_data */
2442         V_VT(&var) = VT_BSTR;
2443         V_BSTR(&var) = SysAllocString(szstr1);
2444         r = IXMLDOMText_put_nodeValue(nodetext, var);
2445         ok(r == S_OK, "ret %08x\n", r );
2446         VariantClear(&var);
2447
2448         r = IXMLDOMText_get_text(nodetext, &str);
2449         ok(r == S_OK, "ret %08x\n", r );
2450         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2451         SysFreeString(str);
2452
2453         /* test put_data */
2454         V_VT(&var) = VT_I4;
2455         V_I4(&var) = 99;
2456         r = IXMLDOMText_put_nodeValue(nodetext, var);
2457         ok(r == S_OK, "ret %08x\n", r );
2458         VariantClear(&var);
2459
2460         r = IXMLDOMText_get_text(nodetext, &str);
2461         ok(r == S_OK, "ret %08x\n", r );
2462         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2463         SysFreeString(str);
2464
2465         /* ::replaceData() */
2466         V_VT(&var) = VT_BSTR;
2467         V_BSTR(&var) = SysAllocString(szstr1);
2468         r = IXMLDOMText_put_nodeValue(nodetext, var);
2469         ok(r == S_OK, "ret %08x\n", r );
2470         VariantClear(&var);
2471
2472         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2473         ok(r == E_INVALIDARG, "ret %08x\n", r );
2474         r = IXMLDOMText_get_text(nodetext, &str);
2475         ok(r == S_OK, "ret %08x\n", r );
2476         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2477         SysFreeString(str);
2478
2479         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2480         ok(r == S_OK, "ret %08x\n", r );
2481         r = IXMLDOMText_get_text(nodetext, &str);
2482         ok(r == S_OK, "ret %08x\n", r );
2483         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2484         SysFreeString(str);
2485
2486         /* NULL pointer means delete */
2487         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2488         ok(r == S_OK, "ret %08x\n", r );
2489         r = IXMLDOMText_get_text(nodetext, &str);
2490         ok(r == S_OK, "ret %08x\n", r );
2491         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2492         SysFreeString(str);
2493
2494         /* empty string means delete */
2495         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2496         ok(r == S_OK, "ret %08x\n", r );
2497         r = IXMLDOMText_get_text(nodetext, &str);
2498         ok(r == S_OK, "ret %08x\n", r );
2499         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2500         SysFreeString(str);
2501
2502         /* zero count means insert */
2503         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2504         ok(r == S_OK, "ret %08x\n", r );
2505         r = IXMLDOMText_get_text(nodetext, &str);
2506         ok(r == S_OK, "ret %08x\n", r );
2507         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2508         SysFreeString(str);
2509
2510         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2511         ok(r == S_OK, "ret %08x\n", r );
2512
2513         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2514         ok(r == S_OK, "ret %08x\n", r );
2515         r = IXMLDOMText_get_text(nodetext, &str);
2516         ok(r == S_OK, "ret %08x\n", r );
2517         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2518         SysFreeString(str);
2519
2520         /* nonempty string, count greater than its length */
2521         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2522         ok(r == S_OK, "ret %08x\n", r );
2523         r = IXMLDOMText_get_text(nodetext, &str);
2524         ok(r == S_OK, "ret %08x\n", r );
2525         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2526         SysFreeString(str);
2527
2528         /* nonempty string, count less than its length */
2529         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2530         ok(r == S_OK, "ret %08x\n", r );
2531         r = IXMLDOMText_get_text(nodetext, &str);
2532         ok(r == S_OK, "ret %08x\n", r );
2533         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2534         SysFreeString(str);
2535
2536         IXMLDOMText_Release( nodetext );
2537     }
2538
2539     /* test Create Comment */
2540     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2541     ok( r == E_INVALIDARG, "returns %08x\n", r );
2542     node_comment = (IXMLDOMComment*)0x1;
2543
2544     /* empty comment */
2545     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2546     ok( r == S_OK, "returns %08x\n", r );
2547     str = (BSTR)0x1;
2548     r = IXMLDOMComment_get_data(node_comment, &str);
2549     ok( r == S_OK, "returns %08x\n", r );
2550     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2551     IXMLDOMComment_Release(node_comment);
2552     SysFreeString(str);
2553
2554     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2555     ok( r == S_OK, "returns %08x\n", r );
2556     str = (BSTR)0x1;
2557     r = IXMLDOMComment_get_data(node_comment, &str);
2558     ok( r == S_OK, "returns %08x\n", r );
2559     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2560     IXMLDOMComment_Release(node_comment);
2561     SysFreeString(str);
2562
2563     str = SysAllocString(szComment);
2564     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2565     SysFreeString(str);
2566     ok( r == S_OK, "returns %08x\n", r );
2567     if(node_comment)
2568     {
2569         /* Last Child Checks */
2570         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2571         ok(r == E_INVALIDARG, "ret %08x\n", r );
2572
2573         nodeChild = (IXMLDOMNode*)0x1;
2574         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2575         ok(r == S_FALSE, "ret %08x\n", r );
2576         ok(nodeChild == NULL, "pLastChild not NULL\n");
2577
2578         /* baseName */
2579         str = (BSTR)0xdeadbeef;
2580         IXMLDOMComment_get_baseName(node_comment, &str);
2581         ok(r == S_FALSE, "ret %08x\n", r );
2582         ok(str == NULL, "Expected NULL\n");
2583
2584         IXMLDOMComment_Release( node_comment );
2585     }
2586
2587     /* test Create Attribute */
2588     str = SysAllocString(szAttribute);
2589     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2590     ok( r == E_INVALIDARG, "returns %08x\n", r );
2591     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2592     ok( r == S_OK, "returns %08x\n", r );
2593     IXMLDOMText_Release( node_attr);
2594     SysFreeString(str);
2595
2596     /* test Processing Instruction */
2597     str = SysAllocStringLen(NULL, 0);
2598     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2599     ok( r == E_INVALIDARG, "returns %08x\n", r );
2600     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2601     ok( r == E_FAIL, "returns %08x\n", r );
2602     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2603     ok( r == E_FAIL, "returns %08x\n", r );
2604     SysFreeString(str);
2605
2606     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2607     ok( r == S_OK, "returns %08x\n", r );
2608     if(nodePI)
2609     {
2610         /* Last Child Checks */
2611         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2612         ok(r == E_INVALIDARG, "ret %08x\n", r );
2613
2614         nodeChild = (IXMLDOMNode*)0x1;
2615         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2616         ok(r == S_FALSE, "ret %08x\n", r );
2617         ok(nodeChild == NULL, "nodeChild not NULL\n");
2618
2619         /* test nodeName */
2620         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2621         ok(r == S_OK, "ret %08x\n", r );
2622         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2623         SysFreeString(str);
2624
2625         /* test baseName */
2626         str = (BSTR)0x1;
2627         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2628         ok(r == S_OK, "ret %08x\n", r );
2629         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2630         SysFreeString(str);
2631
2632         /* test Target */
2633         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2634         ok(r == S_OK, "ret %08x\n", r );
2635         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2636         SysFreeString(str);
2637
2638         /* test get_data */
2639         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2640         ok(r == S_OK, "ret %08x\n", r );
2641         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2642         SysFreeString(str);
2643
2644         /* test put_data */
2645         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2646         ok(r == E_FAIL, "ret %08x\n", r );
2647
2648         /* test put_data */
2649         V_VT(&var) = VT_BSTR;
2650         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2651         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2652         ok(r == E_FAIL, "ret %08x\n", r );
2653         VariantClear(&var);
2654
2655         /* test get nodeName */
2656         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2657         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2658         ok(r == S_OK, "ret %08x\n", r );
2659         SysFreeString(str);
2660
2661         IXMLDOMProcessingInstruction_Release(nodePI);
2662     }
2663
2664     ref = IXMLDOMDocument_Release( doc );
2665     ok( ref == 0, "got %d\n", ref);
2666
2667     free_bstrs();
2668 }
2669
2670 static void test_persiststreaminit(void)
2671 {
2672     IXMLDOMDocument *doc;
2673     IPersistStreamInit *streaminit;
2674     HRESULT hr;
2675
2676     doc = create_document(&IID_IXMLDOMDocument);
2677     if (!doc) return;
2678
2679     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2680     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2681
2682     hr = IPersistStreamInit_InitNew(streaminit);
2683     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2684
2685     IXMLDOMDocument_Release(doc);
2686 }
2687
2688 static void test_domnode( void )
2689 {
2690     HRESULT r;
2691     IXMLDOMDocument *doc, *owner = NULL;
2692     IXMLDOMElement *element = NULL;
2693     IXMLDOMNamedNodeMap *map = NULL;
2694     IXMLDOMNode *node = NULL, *next = NULL;
2695     IXMLDOMNodeList *list = NULL;
2696     IXMLDOMAttribute *attr = NULL;
2697     DOMNodeType type = NODE_INVALID;
2698     VARIANT_BOOL b;
2699     BSTR str;
2700     VARIANT var;
2701     LONG count;
2702
2703     doc = create_document(&IID_IXMLDOMDocument);
2704     if (!doc) return;
2705
2706     b = FALSE;
2707     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2708     ok( r == S_OK, "loadXML failed\n");
2709     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2710
2711     EXPECT_CHILDREN(doc);
2712
2713     r = IXMLDOMDocument_get_documentElement( doc, &element );
2714     ok( r == S_OK, "should be a document element\n");
2715     ok( element != NULL, "should be an element\n");
2716
2717     VariantInit(&var);
2718     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2719
2720     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2721     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2722
2723     r = IXMLDOMNode_get_nodeValue( doc, &var );
2724     ok( r == S_FALSE, "nextNode returned wrong code\n");
2725     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2726     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2727
2728     if (element)
2729     {
2730         owner = NULL;
2731         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2732         ok( r == S_OK, "get_ownerDocument return code\n");
2733         ok( owner != doc, "get_ownerDocument return\n");
2734         IXMLDOMDocument_Release(owner);
2735
2736         type = NODE_INVALID;
2737         r = IXMLDOMNode_get_nodeType( element, &type);
2738         ok( r == S_OK, "got %08x\n", r);
2739         ok( type == NODE_ELEMENT, "node not an element\n");
2740
2741         str = NULL;
2742         r = IXMLDOMNode_get_baseName( element, &str );
2743         ok( r == S_OK, "get_baseName returned wrong code\n");
2744         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2745         SysFreeString(str);
2746
2747         /* check if nodename is correct */
2748         r = IXMLDOMElement_get_nodeName( element, NULL );
2749         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2750
2751         /* content doesn't matter here */
2752         str = NULL;
2753         r = IXMLDOMElement_get_nodeName( element, &str );
2754         ok ( r == S_OK, "get_nodeName wrong code\n");
2755         ok ( str != NULL, "str is null\n");
2756         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2757         SysFreeString( str );
2758
2759         str = SysAllocString( nonexistent_fileW );
2760         V_VT(&var) = VT_I4;
2761         V_I4(&var) = 0x1234;
2762         r = IXMLDOMElement_getAttribute( element, str, &var );
2763         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2764         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2765         VariantClear(&var);
2766
2767         str = SysAllocString( szdl );   
2768         V_VT(&var) = VT_I4;
2769         V_I4(&var) = 0x1234;
2770         r = IXMLDOMElement_getAttribute( element, str, &var );
2771         ok( r == S_OK, "getAttribute ret %08x\n", r );
2772         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2773         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2774         VariantClear( &var );
2775
2776         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2777         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2778
2779         r = IXMLDOMElement_getAttribute( element, str, NULL );
2780         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2781
2782         attr = NULL;
2783         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2784         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2785         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2786         if (attr)
2787         {
2788             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2789             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2790
2791             /* attribute doesn't have a parent in msxml interpretation */
2792             node = (IXMLDOMNode*)0xdeadbeef;
2793             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2794             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2795             ok( node == NULL, "Expected NULL, got %p\n", node );
2796
2797             IXMLDOMAttribute_Release(attr);
2798         }
2799
2800         SysFreeString( str );
2801
2802         r = IXMLDOMElement_get_attributes( element, &map );
2803         ok( r == S_OK, "get_attributes returned wrong code\n");
2804         ok( map != NULL, "should be attributes\n");
2805
2806         EXPECT_CHILDREN(element);
2807     }
2808     else
2809         ok( FALSE, "no element\n");
2810
2811     if (map)
2812     {
2813         str = SysAllocString( szdl );
2814         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2815         ok( r == S_OK, "getNamedItem returned wrong code\n");
2816         ok( node != NULL, "should be attributes\n");
2817         IXMLDOMNode_Release(node);
2818         SysFreeString( str );
2819
2820         str = SysAllocString( szdl );
2821         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2822         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2823         SysFreeString( str );
2824
2825         /* something that isn't in complete4A */
2826         str = SysAllocString( szOpen );
2827         node = (IXMLDOMNode *) 1;
2828         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2829         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2830         ok( node == NULL, "getNamedItem should have returned NULL\n");
2831         SysFreeString( str );
2832
2833         /* test indexed access of attributes */
2834         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2835         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2836
2837         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2838         ok ( r == S_OK, "get_length wrong code\n");
2839         ok ( count == 1, "get_length != 1\n");
2840
2841         node = NULL;
2842         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2843         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2844         ok ( node == NULL, "there is no node\n");
2845
2846         node = NULL;
2847         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2848         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2849         ok ( node == NULL, "there is no attribute\n");
2850
2851         node = NULL;
2852         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2853         ok ( r == S_OK, "get_item (0) wrong code\n");
2854         ok ( node != NULL, "should be attribute\n");
2855
2856         r = IXMLDOMNode_get_nodeName( node, NULL );
2857         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2858
2859         /* content doesn't matter here */
2860         str = NULL;
2861         r = IXMLDOMNode_get_nodeName( node, &str );
2862         ok ( r == S_OK, "get_nodeName wrong code\n");
2863         ok ( str != NULL, "str is null\n");
2864         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2865         SysFreeString( str );
2866         IXMLDOMNode_Release( node );
2867
2868         /* test sequential access of attributes */
2869         node = NULL;
2870         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2871         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2872         ok ( node != NULL, "nextNode, should be attribute\n");
2873         IXMLDOMNode_Release( node );
2874
2875         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2876         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2877         ok ( node == NULL, "nextNode, there is no attribute\n");
2878
2879         r = IXMLDOMNamedNodeMap_reset( map );
2880         ok ( r == S_OK, "reset should return S_OK\n");
2881
2882         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2883         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2884         ok ( node != NULL, "nextNode, should be attribute\n");
2885     }
2886     else
2887         ok( FALSE, "no map\n");
2888
2889     if (node)
2890     {
2891         type = NODE_INVALID;
2892         r = IXMLDOMNode_get_nodeType( node, &type);
2893         ok( r == S_OK, "getNamedItem returned wrong code\n");
2894         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2895
2896         str = NULL;
2897         r = IXMLDOMNode_get_baseName( node, NULL );
2898         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2899
2900         str = NULL;
2901         r = IXMLDOMNode_get_baseName( node, &str );
2902         ok( r == S_OK, "get_baseName returned wrong code\n");
2903         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2904         SysFreeString( str );
2905
2906         r = IXMLDOMNode_get_childNodes( node, NULL );
2907         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2908
2909         r = IXMLDOMNode_get_childNodes( node, &list );
2910         ok( r == S_OK, "get_childNodes returned wrong code\n");
2911
2912         if (list)
2913         {
2914             r = IXMLDOMNodeList_nextNode( list, &next );
2915             ok( r == S_OK, "nextNode returned wrong code\n");
2916         }
2917         else
2918             ok( FALSE, "no childlist\n");
2919
2920         if (next)
2921         {
2922             EXPECT_NO_CHILDREN(next);
2923
2924             type = NODE_INVALID;
2925             r = IXMLDOMNode_get_nodeType( next, &type);
2926             ok( r == S_OK, "getNamedItem returned wrong code\n");
2927             ok( type == NODE_TEXT, "node not text\n");
2928
2929             str = (BSTR) 1;
2930             r = IXMLDOMNode_get_baseName( next, &str );
2931             ok( r == S_FALSE, "get_baseName returned wrong code\n");
2932             ok( str == NULL, "basename was wrong\n");
2933             SysFreeString(str);
2934         }
2935         else
2936             ok( FALSE, "no next\n");
2937
2938         if (next)
2939             IXMLDOMNode_Release( next );
2940         next = NULL;
2941         if (list)
2942             IXMLDOMNodeList_Release( list );
2943         list = NULL;
2944         if (node)
2945             IXMLDOMNode_Release( node );
2946     }
2947     else
2948         ok( FALSE, "no node\n");
2949     node = NULL;
2950
2951     if (map)
2952         IXMLDOMNamedNodeMap_Release( map );
2953
2954     /* now traverse the tree from the root element */
2955     if (element)
2956     {
2957         r = IXMLDOMNode_get_childNodes( element, &list );
2958         ok( r == S_OK, "get_childNodes returned wrong code\n");
2959
2960         /* using get_item for child list doesn't advance the position */
2961         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2962         expect_node(node, "E2.E2.D1");
2963         IXMLDOMNode_Release(node);
2964         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2965         expect_node(node, "E1.E2.D1");
2966         IXMLDOMNode_Release(node);
2967         ole_check(IXMLDOMNodeList_reset(list));
2968
2969         IXMLDOMNodeList_AddRef(list);
2970         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2971         ole_check(IXMLDOMNodeList_reset(list));
2972
2973         node = (void*)0xdeadbeef;
2974         str = SysAllocString(szdl);
2975         r = IXMLDOMNode_selectSingleNode( element, str, &node );
2976         SysFreeString(str);
2977         ok( r == S_FALSE, "ret %08x\n", r );
2978         ok( node == NULL, "node %p\n", node );
2979
2980         str = SysAllocString(szbs);
2981         r = IXMLDOMNode_selectSingleNode( element, str, &node );
2982         SysFreeString(str);
2983         ok( r == S_OK, "ret %08x\n", r );
2984         r = IXMLDOMNode_Release( node );
2985         ok( r == 0, "ret %08x\n", r );
2986     }
2987     else
2988         ok( FALSE, "no element\n");
2989
2990     if (list)
2991     {
2992         r = IXMLDOMNodeList_get_item(list, 0, NULL);
2993         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2994
2995         r = IXMLDOMNodeList_get_length(list, NULL);
2996         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2997
2998         r = IXMLDOMNodeList_get_length( list, &count );
2999         ok( r == S_OK, "get_length returns %08x\n", r );
3000         ok( count == 4, "get_length got %d\n", count );
3001
3002         r = IXMLDOMNodeList_nextNode(list, NULL);
3003         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3004
3005         r = IXMLDOMNodeList_nextNode( list, &node );
3006         ok( r == S_OK, "nextNode returned wrong code\n");
3007     }
3008     else
3009         ok( FALSE, "no list\n");
3010
3011     if (node)
3012     {
3013         type = NODE_INVALID;
3014         r = IXMLDOMNode_get_nodeType( node, &type);
3015         ok( r == S_OK, "getNamedItem returned wrong code\n");
3016         ok( type == NODE_ELEMENT, "node not text\n");
3017
3018         r = IXMLDOMNode_hasChildNodes( node, NULL );
3019         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3020
3021         EXPECT_CHILDREN(node);
3022
3023         str = NULL;
3024         r = IXMLDOMNode_get_baseName( node, &str );
3025         ok( r == S_OK, "get_baseName returned wrong code\n");
3026         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3027         SysFreeString(str);
3028     }
3029     else
3030         ok( FALSE, "no node\n");
3031
3032     if (node)
3033         IXMLDOMNode_Release( node );
3034     if (list)
3035         IXMLDOMNodeList_Release( list );
3036     if (element)
3037         IXMLDOMElement_Release( element );
3038
3039     b = FALSE;
3040     str = SysAllocString( szComplete5 );
3041     r = IXMLDOMDocument_loadXML( doc, str, &b );
3042     ok( r == S_OK, "loadXML failed\n");
3043     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3044     SysFreeString( str );
3045
3046     EXPECT_CHILDREN(doc);
3047
3048     r = IXMLDOMDocument_get_documentElement( doc, &element );
3049     ok( r == S_OK, "should be a document element\n");
3050     ok( element != NULL, "should be an element\n");
3051
3052     if (element)
3053     {
3054         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3055         BSTR tag = NULL;
3056
3057         /* check if the tag is correct */
3058         r = IXMLDOMElement_get_tagName( element, &tag );
3059         ok( r == S_OK, "couldn't get tag name\n");
3060         ok( tag != NULL, "tag was null\n");
3061         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3062         SysFreeString( tag );
3063     }
3064
3065     if (element)
3066         IXMLDOMElement_Release( element );
3067     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3068
3069     free_bstrs();
3070 }
3071
3072 typedef struct {
3073     DOMNodeType type;
3074     REFIID iid;
3075 } refcount_test_t;
3076
3077 static const refcount_test_t refcount_test[] = {
3078     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3079     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3080     { NODE_TEXT,                   &IID_IXMLDOMText },
3081     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3082     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3083     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3084     { NODE_COMMENT,                &IID_IXMLDOMComment },
3085     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3086     { NODE_INVALID,                &IID_NULL }
3087 };
3088
3089 static void test_refs(void)
3090 {
3091     IXMLDOMImplementation *impl, *impl2;
3092     IXMLDOMElement *element, *elem2;
3093     IXMLDOMNodeList *node_list = NULL;
3094     IXMLDOMNode *node, *node2, *node3;
3095     const refcount_test_t *ptr;
3096     IXMLDOMDocument *doc;
3097     IUnknown *unk, *unk2;
3098     VARIANT_BOOL b;
3099     HRESULT hr;
3100     LONG ref;
3101
3102     doc = create_document(&IID_IXMLDOMDocument);
3103     if (!doc) return;
3104
3105     ptr = refcount_test;
3106     while (ptr->type != NODE_INVALID)
3107     {
3108         IUnknown *node_typed, *node_typed2;
3109         IDispatchEx *dispex, *dispex2;
3110         IDispatch *disp, *disp2;
3111         VARIANT type;
3112
3113         V_VT(&type) = VT_I1;
3114         V_I1(&type) = ptr->type;
3115
3116         EXPECT_REF(doc, 1);
3117         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3118         EXPECT_HR(hr, S_OK);
3119         EXPECT_REF(doc, 1);
3120         EXPECT_REF(node, 1);
3121
3122         /* try IDispatch and IUnknown from IXMLDOMNode */
3123         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3124         EXPECT_HR(hr, S_OK);
3125         EXPECT_REF(unk, 2);
3126 todo_wine {
3127         EXPECT_REF(node, 1);
3128         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3129 }
3130         EXPECT_REF(unk, 2);
3131         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3132         EXPECT_HR(hr, S_OK);
3133         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3134         EXPECT_REF(unk, 3);
3135         todo_wine EXPECT_REF(disp, 1);
3136
3137         EXPECT_REF(unk, 3);
3138         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3139         EXPECT_HR(hr, S_OK);
3140         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3141         EXPECT_REF(unk, 4);
3142         todo_wine EXPECT_REF(disp2, 1);
3143
3144         IDispatch_Release(disp);
3145         IDispatch_Release(disp2);
3146
3147         /* get IXMLDOMNode from this IUnknown */
3148         EXPECT_REF(unk, 2);
3149         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3150         EXPECT_HR(hr, S_OK);
3151         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3152         EXPECT_REF(unk, 3);
3153         todo_wine EXPECT_REF(node2, 1);
3154
3155         EXPECT_REF(unk, 3);
3156         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3157         EXPECT_HR(hr, S_OK);
3158         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3159         EXPECT_REF(unk, 4);
3160         todo_wine EXPECT_REF(node3, 1);
3161
3162         IXMLDOMNode_Release(node2);
3163         IXMLDOMNode_Release(node3);
3164
3165         /* try IDispatchEx from IUnknown */
3166         EXPECT_REF(unk, 2);
3167         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3168         EXPECT_HR(hr, S_OK);
3169         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3170         EXPECT_REF(unk, 3);
3171         todo_wine EXPECT_REF(dispex, 1);
3172
3173         EXPECT_REF(unk, 3);
3174         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3175         EXPECT_HR(hr, S_OK);
3176         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3177         EXPECT_REF(unk, 4);
3178         todo_wine EXPECT_REF(dispex2, 1);
3179
3180         IDispatch_Release(dispex);
3181         IDispatch_Release(dispex2);
3182
3183         /* try corresponding IXMLDOM* */
3184         EXPECT_REF(unk, 2);
3185         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3186         EXPECT_HR(hr, S_OK);
3187         EXPECT_REF(unk, 3);
3188         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3189         EXPECT_HR(hr, S_OK);
3190         EXPECT_REF(unk, 4);
3191         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3192         IUnknown_Release(node_typed);
3193         IUnknown_Release(node_typed2);
3194
3195         /* try invalid IXMLDOM* */
3196         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3197         EXPECT_HR(hr, E_NOINTERFACE);
3198
3199         IUnknown_Release(unk);
3200
3201         EXPECT_REF(node, 1);
3202         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3203         EXPECT_HR(hr, S_OK);
3204         EXPECT_REF(node, 2);
3205         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3206
3207         EXPECT_REF(node, 2);
3208         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3209         EXPECT_HR(hr, S_OK);
3210         EXPECT_REF(node, 3);
3211 todo_wine {
3212         EXPECT_REF(node_typed, 2);
3213         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3214 }
3215         IUnknown_Release(node_typed);
3216
3217         IXMLDOMNode_Release(node2);
3218         IXMLDOMNode_Release(node);
3219
3220         ptr++;
3221     }
3222
3223     EXPECT_REF(doc, 1);
3224     ref = IXMLDOMDocument_Release(doc);
3225     ok( ref == 0, "ref %d\n", ref);
3226
3227     /* check IUnknown after releasing DOM iface */
3228     doc = create_document(&IID_IXMLDOMDocument);
3229     EXPECT_REF(doc, 1);
3230     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3231     EXPECT_HR(hr, S_OK);
3232 todo_wine {
3233     EXPECT_REF(unk, 3);
3234     EXPECT_REF(doc, 1);
3235 }
3236     IXMLDOMDocument_Release(doc);
3237     EXPECT_REF(unk, 1);
3238     IUnknown_Release(unk);
3239
3240     doc = create_document(&IID_IXMLDOMDocument);
3241     if (!doc) return;
3242
3243     EXPECT_REF(doc, 1);
3244     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3245     EXPECT_HR(hr, S_OK);
3246 todo_wine {
3247     EXPECT_REF(unk, 3);
3248     EXPECT_REF(doc, 1);
3249 }
3250     IUnknown_Release(unk);
3251
3252     /* IXMLDOMImplementation */
3253     EXPECT_REF(doc, 1);
3254     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3255     EXPECT_HR(hr, S_OK);
3256     EXPECT_REF(doc, 1);
3257     EXPECT_REF(impl, 1);
3258     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3259     EXPECT_HR(hr, S_OK);
3260     EXPECT_REF(doc, 1);
3261     EXPECT_REF(impl2, 1);
3262     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3263     IXMLDOMImplementation_Release(impl);
3264     IXMLDOMImplementation_Release(impl2);
3265
3266     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3267     EXPECT_HR(hr, S_OK);
3268     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3269
3270     EXPECT_REF(doc, 1);
3271     IXMLDOMDocument_AddRef( doc );
3272     EXPECT_REF(doc, 2);
3273     IXMLDOMDocument_AddRef( doc );
3274     EXPECT_REF(doc, 3);
3275
3276     IXMLDOMDocument_Release( doc );
3277     IXMLDOMDocument_Release( doc );
3278
3279     EXPECT_REF(doc, 1);
3280     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3281     EXPECT_HR(hr, S_OK);
3282 todo_wine {
3283     EXPECT_REF(unk, 3);
3284     EXPECT_REF(doc, 1);
3285 }
3286     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3287     EXPECT_HR(hr, S_OK);
3288 todo_wine {
3289     EXPECT_REF(doc, 1);
3290     EXPECT_REF(element, 2);
3291 }
3292     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3293     EXPECT_HR(hr, S_OK);
3294
3295 todo_wine {
3296     EXPECT_REF(doc, 1);
3297     EXPECT_REF(element, 2);
3298     EXPECT_REF(elem2, 2);
3299 }
3300     IXMLDOMElement_AddRef(element);
3301     todo_wine EXPECT_REF(element, 3);
3302     IXMLDOMElement_Release(element);
3303
3304     /* get IUnknown from a node doesn't touch node instance refcount */
3305     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3306     EXPECT_HR(hr, S_OK);
3307     EXPECT_REF(element, 2);
3308 todo_wine {
3309     EXPECT_REF(unk, 4);
3310     EXPECT_REF(elem2, 2);
3311 }
3312     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3313     EXPECT_HR(hr, S_OK);
3314 todo_wine {
3315     EXPECT_REF(unk, 5);
3316     EXPECT_REF(unk2, 5);
3317 }
3318     EXPECT_REF(element, 2);
3319     EXPECT_REF(elem2, 2);
3320
3321     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3322
3323     IUnknown_Release(unk);
3324     IUnknown_Release(unk2);
3325
3326     /* IUnknown refcount is not affected by node refcount */
3327     todo_wine EXPECT_REF(unk2, 3);
3328     IXMLDOMElement_AddRef(elem2);
3329     todo_wine EXPECT_REF(unk2, 3);
3330     IXMLDOMElement_Release(elem2);
3331
3332     IXMLDOMElement_Release(elem2);
3333     todo_wine EXPECT_REF(unk2, 2);
3334
3335     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3336     EXPECT_HR(hr, S_OK);
3337
3338     todo_wine EXPECT_REF(element, 2);
3339     EXPECT_REF(node_list, 1);
3340
3341     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3342     EXPECT_HR(hr, S_OK);
3343     EXPECT_REF(node_list, 1);
3344     EXPECT_REF(node, 1);
3345
3346     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3347     EXPECT_HR(hr, S_OK);
3348     EXPECT_REF(node_list, 1);
3349     EXPECT_REF(node2, 1);
3350
3351     ref = IXMLDOMNode_Release( node );
3352     ok( ref == 0, "ref %d\n", ref );
3353     ref = IXMLDOMNode_Release( node2 );
3354     ok( ref == 0, "ref %d\n", ref );
3355
3356     ref = IXMLDOMNodeList_Release( node_list );
3357     ok( ref == 0, "ref %d\n", ref );
3358
3359     ok( node != node2, "node %p node2 %p\n", node, node2 );
3360
3361     ref = IXMLDOMDocument_Release( doc );
3362     todo_wine ok( ref == 0, "ref %d\n", ref );
3363
3364     todo_wine EXPECT_REF(element, 2);
3365
3366     /* IUnknown must be unique however we obtain it */
3367     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3368     EXPECT_HR(hr, S_OK);
3369     EXPECT_REF(element, 2);
3370     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3371     EXPECT_HR(hr, S_OK);
3372     todo_wine EXPECT_REF(element, 2);
3373     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3374     EXPECT_HR(hr, S_OK);
3375     todo_wine EXPECT_REF(element, 2);
3376     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3377     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3378
3379     IUnknown_Release( unk2 );
3380     IUnknown_Release( unk );
3381     IXMLDOMNode_Release( node );
3382     todo_wine EXPECT_REF(element, 2);
3383
3384     IXMLDOMElement_Release( element );
3385
3386     free_bstrs();
3387 }
3388
3389 static void test_create(void)
3390 {
3391     static const WCHAR szOne[] = {'1',0};
3392     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3393     HRESULT r;
3394     VARIANT var;
3395     BSTR str, name;
3396     IXMLDOMDocument *doc;
3397     IXMLDOMElement *element;
3398     IXMLDOMComment *comment;
3399     IXMLDOMText *text;
3400     IXMLDOMCDATASection *cdata;
3401     IXMLDOMNode *root, *node, *child;
3402     IXMLDOMNamedNodeMap *attr_map;
3403     IUnknown *unk;
3404     LONG ref;
3405     LONG num;
3406
3407     doc = create_document(&IID_IXMLDOMDocument);
3408     if (!doc) return;
3409
3410     EXPECT_REF(doc, 1);
3411
3412     /* types not supported for creation */
3413     V_VT(&var) = VT_I1;
3414     V_I1(&var) = NODE_DOCUMENT;
3415     node = (IXMLDOMNode*)0x1;
3416     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3417     ok( r == E_INVALIDARG, "returns %08x\n", r );
3418     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3419
3420     V_VT(&var) = VT_I1;
3421     V_I1(&var) = NODE_DOCUMENT_TYPE;
3422     node = (IXMLDOMNode*)0x1;
3423     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3424     ok( r == E_INVALIDARG, "returns %08x\n", r );
3425     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3426
3427     V_VT(&var) = VT_I1;
3428     V_I1(&var) = NODE_ENTITY;
3429     node = (IXMLDOMNode*)0x1;
3430     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3431     ok( r == E_INVALIDARG, "returns %08x\n", r );
3432     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3433
3434     V_VT(&var) = VT_I1;
3435     V_I1(&var) = NODE_NOTATION;
3436     node = (IXMLDOMNode*)0x1;
3437     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3438     ok( r == E_INVALIDARG, "returns %08x\n", r );
3439     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3440
3441     /* NODE_COMMENT */
3442     V_VT(&var) = VT_I1;
3443     V_I1(&var) = NODE_COMMENT;
3444     node = NULL;
3445     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3446     ok( r == S_OK, "returns %08x\n", r );
3447     ok( node != NULL, "\n");
3448
3449     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3450     ok( r == S_OK, "returns %08x\n", r );
3451     IXMLDOMNode_Release(node);
3452
3453     str = NULL;
3454     r = IXMLDOMComment_get_data(comment, &str);
3455     ok( r == S_OK, "returns %08x\n", r );
3456     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3457     IXMLDOMComment_Release(comment);
3458     SysFreeString(str);
3459
3460     node = (IXMLDOMNode*)0x1;
3461     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3462     ok( r == S_OK, "returns %08x\n", r );
3463
3464     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3465     ok( r == S_OK, "returns %08x\n", r );
3466     IXMLDOMNode_Release(node);
3467
3468     str = NULL;
3469     r = IXMLDOMComment_get_data(comment, &str);
3470     ok( r == S_OK, "returns %08x\n", r );
3471     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3472     IXMLDOMComment_Release(comment);
3473     SysFreeString(str);
3474
3475     node = (IXMLDOMNode*)0x1;
3476     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3477     ok( r == S_OK, "returns %08x\n", r );
3478
3479     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3480     ok( r == S_OK, "returns %08x\n", r );
3481     IXMLDOMNode_Release(node);
3482
3483     str = NULL;
3484     r = IXMLDOMComment_get_data(comment, &str);
3485     ok( r == S_OK, "returns %08x\n", r );
3486     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3487     IXMLDOMComment_Release(comment);
3488     SysFreeString(str);
3489
3490     /* NODE_TEXT */
3491     V_VT(&var) = VT_I1;
3492     V_I1(&var) = NODE_TEXT;
3493     node = NULL;
3494     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3495     ok( r == S_OK, "returns %08x\n", r );
3496     ok( node != NULL, "\n");
3497
3498     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3499     ok( r == S_OK, "returns %08x\n", r );
3500     IXMLDOMNode_Release(node);
3501
3502     str = NULL;
3503     r = IXMLDOMText_get_data(text, &str);
3504     ok( r == S_OK, "returns %08x\n", r );
3505     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3506     IXMLDOMText_Release(text);
3507     SysFreeString(str);
3508
3509     node = (IXMLDOMNode*)0x1;
3510     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3511     ok( r == S_OK, "returns %08x\n", r );
3512
3513     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3514     ok( r == S_OK, "returns %08x\n", r );
3515     IXMLDOMNode_Release(node);
3516
3517     str = NULL;
3518     r = IXMLDOMText_get_data(text, &str);
3519     ok( r == S_OK, "returns %08x\n", r );
3520     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3521     IXMLDOMText_Release(text);
3522     SysFreeString(str);
3523
3524     node = (IXMLDOMNode*)0x1;
3525     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3526     ok( r == S_OK, "returns %08x\n", r );
3527
3528     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3529     ok( r == S_OK, "returns %08x\n", r );
3530     IXMLDOMNode_Release(node);
3531
3532     str = NULL;
3533     r = IXMLDOMText_get_data(text, &str);
3534     ok( r == S_OK, "returns %08x\n", r );
3535     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3536     IXMLDOMText_Release(text);
3537     SysFreeString(str);
3538
3539     /* NODE_CDATA_SECTION */
3540     V_VT(&var) = VT_I1;
3541     V_I1(&var) = NODE_CDATA_SECTION;
3542     node = NULL;
3543     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3544     ok( r == S_OK, "returns %08x\n", r );
3545     ok( node != NULL, "\n");
3546
3547     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3548     ok( r == S_OK, "returns %08x\n", r );
3549     IXMLDOMNode_Release(node);
3550
3551     str = NULL;
3552     r = IXMLDOMCDATASection_get_data(cdata, &str);
3553     ok( r == S_OK, "returns %08x\n", r );
3554     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3555     IXMLDOMCDATASection_Release(cdata);
3556     SysFreeString(str);
3557
3558     node = (IXMLDOMNode*)0x1;
3559     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3560     ok( r == S_OK, "returns %08x\n", r );
3561
3562     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3563     ok( r == S_OK, "returns %08x\n", r );
3564     IXMLDOMNode_Release(node);
3565
3566     str = NULL;
3567     r = IXMLDOMCDATASection_get_data(cdata, &str);
3568     ok( r == S_OK, "returns %08x\n", r );
3569     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3570     IXMLDOMCDATASection_Release(cdata);
3571     SysFreeString(str);
3572
3573     node = (IXMLDOMNode*)0x1;
3574     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3575     ok( r == S_OK, "returns %08x\n", r );
3576
3577     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3578     ok( r == S_OK, "returns %08x\n", r );
3579     IXMLDOMNode_Release(node);
3580
3581     str = NULL;
3582     r = IXMLDOMCDATASection_get_data(cdata, &str);
3583     ok( r == S_OK, "returns %08x\n", r );
3584     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3585     IXMLDOMCDATASection_Release(cdata);
3586     SysFreeString(str);
3587
3588     /* NODE_ATTRIBUTE */
3589     V_VT(&var) = VT_I1;
3590     V_I1(&var) = NODE_ATTRIBUTE;
3591     node = (IXMLDOMNode*)0x1;
3592     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3593     ok( r == E_FAIL, "returns %08x\n", r );
3594     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3595
3596     V_VT(&var) = VT_I1;
3597     V_I1(&var) = NODE_ATTRIBUTE;
3598     node = (IXMLDOMNode*)0x1;
3599     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3600     ok( r == E_FAIL, "returns %08x\n", r );
3601     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3602
3603     V_VT(&var) = VT_I1;
3604     V_I1(&var) = NODE_ATTRIBUTE;
3605     str = SysAllocString( szlc );
3606     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3607     ok( r == S_OK, "returns %08x\n", r );
3608     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3609     SysFreeString(str);
3610
3611     /* a name is required for attribute, try a BSTR with first null wchar */
3612     V_VT(&var) = VT_I1;
3613     V_I1(&var) = NODE_ATTRIBUTE;
3614     str = SysAllocString( szstr1 );
3615     str[0] = 0;
3616     node = (IXMLDOMNode*)0x1;
3617     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3618     ok( r == E_FAIL, "returns %08x\n", r );
3619     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3620     SysFreeString(str);
3621
3622     /* NODE_PROCESSING_INSTRUCTION */
3623     V_VT(&var) = VT_I1;
3624     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3625     node = (IXMLDOMNode*)0x1;
3626     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3627     ok( r == E_FAIL, "returns %08x\n", r );
3628     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3629
3630     V_VT(&var) = VT_I1;
3631     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3632     node = (IXMLDOMNode*)0x1;
3633     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3634     ok( r == E_FAIL, "returns %08x\n", r );
3635     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3636
3637     V_VT(&var) = VT_I1;
3638     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3639     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3640     ok( r == E_INVALIDARG, "returns %08x\n", r );
3641
3642     /* NODE_ENTITY_REFERENCE */
3643     V_VT(&var) = VT_I1;
3644     V_I1(&var) = NODE_ENTITY_REFERENCE;
3645     node = (IXMLDOMNode*)0x1;
3646     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3647     ok( r == E_FAIL, "returns %08x\n", r );
3648     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3649
3650     V_VT(&var) = VT_I1;
3651     V_I1(&var) = NODE_ENTITY_REFERENCE;
3652     node = (IXMLDOMNode*)0x1;
3653     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3654     ok( r == E_FAIL, "returns %08x\n", r );
3655     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3656
3657     /* NODE_ELEMENT */
3658     V_VT(&var) = VT_I1;
3659     V_I1(&var) = NODE_ELEMENT;
3660     node = (IXMLDOMNode*)0x1;
3661     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3662     ok( r == E_FAIL, "returns %08x\n", r );
3663     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3664
3665     V_VT(&var) = VT_I1;
3666     V_I1(&var) = NODE_ELEMENT;
3667     node = (IXMLDOMNode*)0x1;
3668     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3669     ok( r == E_FAIL, "returns %08x\n", r );
3670     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3671
3672     V_VT(&var) = VT_I1;
3673     V_I1(&var) = NODE_ELEMENT;
3674     str = SysAllocString( szlc );
3675     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3676     ok( r == S_OK, "returns %08x\n", r );
3677     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3678
3679     V_VT(&var) = VT_I1;
3680     V_I1(&var) = NODE_ELEMENT;
3681     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3682     ok( r == E_INVALIDARG, "returns %08x\n", r );
3683
3684     V_VT(&var) = VT_R4;
3685     V_R4(&var) = NODE_ELEMENT;
3686     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3687     ok( r == S_OK, "returns %08x\n", r );
3688     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3689
3690     V_VT(&var) = VT_BSTR;
3691     V_BSTR(&var) = SysAllocString( szOne );
3692     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3693     ok( r == S_OK, "returns %08x\n", r );
3694     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3695     VariantClear(&var);
3696
3697     V_VT(&var) = VT_BSTR;
3698     V_BSTR(&var) = SysAllocString( szOneGarbage );
3699     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3700     ok( r == E_INVALIDARG, "returns %08x\n", r );
3701     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3702     VariantClear(&var);
3703
3704     V_VT(&var) = VT_I4;
3705     V_I4(&var) = NODE_ELEMENT;
3706     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3707     ok( r == S_OK, "returns %08x\n", r );
3708
3709     EXPECT_REF(doc, 1);
3710     r = IXMLDOMDocument_appendChild( doc, node, &root );
3711     ok( r == S_OK, "returns %08x\n", r );
3712     ok( node == root, "%p %p\n", node, root );
3713     EXPECT_REF(doc, 1);
3714
3715     EXPECT_REF(node, 2);
3716
3717     ref = IXMLDOMNode_Release( node );
3718     ok(ref == 1, "ref %d\n", ref);
3719     SysFreeString( str );
3720
3721     V_VT(&var) = VT_I4;
3722     V_I4(&var) = NODE_ELEMENT;
3723     str = SysAllocString( szbs );
3724     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3725     ok( r == S_OK, "returns %08x\n", r );
3726     SysFreeString( str );
3727
3728     EXPECT_REF(node, 1);
3729
3730     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3731     ok( r == S_OK, "returns %08x\n", r );
3732
3733     EXPECT_REF(unk, 2);
3734
3735     V_VT(&var) = VT_EMPTY;
3736     child = NULL;
3737     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3738     ok( r == S_OK, "returns %08x\n", r );
3739     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3740
3741     todo_wine EXPECT_REF(unk, 4);
3742
3743     IXMLDOMNode_Release( child );
3744     IUnknown_Release( unk );
3745
3746     V_VT(&var) = VT_NULL;
3747     V_DISPATCH(&var) = (IDispatch*)node;
3748     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3749     ok( r == S_OK, "returns %08x\n", r );
3750     ok( node == child, "%p %p\n", node, child );
3751     IXMLDOMNode_Release( child );
3752
3753     V_VT(&var) = VT_NULL;
3754     V_DISPATCH(&var) = (IDispatch*)node;
3755     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3756     ok( r == S_OK, "returns %08x\n", r );
3757     IXMLDOMNode_Release( node );
3758
3759     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3760     ok( r == S_OK, "returns %08x\n", r );
3761
3762     r = IXMLDOMElement_get_attributes( element, &attr_map );
3763     ok( r == S_OK, "returns %08x\n", r );
3764     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3765     ok( r == S_OK, "returns %08x\n", r );
3766     ok( num == 0, "num %d\n", num );
3767     IXMLDOMNamedNodeMap_Release( attr_map );
3768
3769     V_VT(&var) = VT_BSTR;
3770     V_BSTR(&var) = SysAllocString( szstr1 );
3771     name = SysAllocString( szdl );
3772     r = IXMLDOMElement_setAttribute( element, name, var );
3773     ok( r == S_OK, "returns %08x\n", r );
3774     r = IXMLDOMElement_get_attributes( element, &attr_map );
3775     ok( r == S_OK, "returns %08x\n", r );
3776     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3777     ok( r == S_OK, "returns %08x\n", r );
3778     ok( num == 1, "num %d\n", num );
3779     IXMLDOMNamedNodeMap_Release( attr_map );
3780     VariantClear(&var);
3781
3782     V_VT(&var) = VT_BSTR;
3783     V_BSTR(&var) = SysAllocString( szstr2 );
3784     r = IXMLDOMElement_setAttribute( element, name, var );
3785     ok( r == S_OK, "returns %08x\n", r );
3786     r = IXMLDOMElement_get_attributes( element, &attr_map );
3787     ok( r == S_OK, "returns %08x\n", r );
3788     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3789     ok( r == S_OK, "returns %08x\n", r );
3790     ok( num == 1, "num %d\n", num );
3791     IXMLDOMNamedNodeMap_Release( attr_map );
3792     VariantClear(&var);
3793     r = IXMLDOMElement_getAttribute( element, name, &var );
3794     ok( r == S_OK, "returns %08x\n", r );
3795     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3796     VariantClear(&var);
3797     SysFreeString(name);
3798
3799     V_VT(&var) = VT_BSTR;
3800     V_BSTR(&var) = SysAllocString( szstr1 );
3801     name = SysAllocString( szlc );
3802     r = IXMLDOMElement_setAttribute( element, name, var );
3803     ok( r == S_OK, "returns %08x\n", r );
3804     r = IXMLDOMElement_get_attributes( element, &attr_map );
3805     ok( r == S_OK, "returns %08x\n", r );
3806     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3807     ok( r == S_OK, "returns %08x\n", r );
3808     ok( num == 2, "num %d\n", num );
3809     IXMLDOMNamedNodeMap_Release( attr_map );
3810     VariantClear(&var);
3811     SysFreeString(name);
3812
3813     V_VT(&var) = VT_I4;
3814     V_I4(&var) = 10;
3815     name = SysAllocString( szbs );
3816     r = IXMLDOMElement_setAttribute( element, name, var );
3817     ok( r == S_OK, "returns %08x\n", r );
3818     VariantClear(&var);
3819     r = IXMLDOMElement_getAttribute( element, name, &var );
3820     ok( r == S_OK, "returns %08x\n", r );
3821     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3822     VariantClear(&var);
3823     SysFreeString(name);
3824
3825     /* Create an Attribute */
3826     V_VT(&var) = VT_I4;
3827     V_I4(&var) = NODE_ATTRIBUTE;
3828     str = SysAllocString( szAttribute );
3829     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3830     ok( r == S_OK, "returns %08x\n", r );
3831     ok( node != NULL, "node was null\n");
3832     SysFreeString(str);
3833
3834     IXMLDOMElement_Release( element );
3835     IXMLDOMNode_Release( root );
3836     IXMLDOMDocument_Release( doc );
3837 }
3838
3839 static void test_getElementsByTagName(void)
3840 {
3841     IXMLDOMNodeList *node_list;
3842     IXMLDOMDocument *doc;
3843     IXMLDOMElement *elem;
3844     WCHAR buff[100];
3845     VARIANT_BOOL b;
3846     HRESULT r;
3847     LONG len;
3848     BSTR str;
3849
3850     doc = create_document(&IID_IXMLDOMDocument);
3851     if (!doc) return;
3852
3853     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3854     ok( r == S_OK, "loadXML failed\n");
3855     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3856
3857     str = SysAllocString( szstar );
3858
3859     /* null arguments cases */
3860     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3861     ok( r == E_INVALIDARG, "ret %08x\n", r );
3862     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3863     ok( r == E_INVALIDARG, "ret %08x\n", r );
3864
3865     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3866     ok( r == S_OK, "ret %08x\n", r );
3867     r = IXMLDOMNodeList_get_length( node_list, &len );
3868     ok( r == S_OK, "ret %08x\n", r );
3869     ok( len == 6, "len %d\n", len );
3870
3871     IXMLDOMNodeList_Release( node_list );
3872     SysFreeString( str );
3873
3874     /* broken query BSTR */
3875     memcpy(&buff[2], szstar, sizeof(szstar));
3876     /* just a big length */
3877     *(DWORD*)buff = 0xf0f0;
3878     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3879     ok( r == S_OK, "ret %08x\n", r );
3880     r = IXMLDOMNodeList_get_length( node_list, &len );
3881     ok( r == S_OK, "ret %08x\n", r );
3882     ok( len == 6, "len %d\n", len );
3883     IXMLDOMNodeList_Release( node_list );
3884
3885     str = SysAllocString( szbs );
3886     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3887     ok( r == S_OK, "ret %08x\n", r );
3888     r = IXMLDOMNodeList_get_length( node_list, &len );
3889     ok( r == S_OK, "ret %08x\n", r );
3890     ok( len == 1, "len %d\n", len );
3891     IXMLDOMNodeList_Release( node_list );
3892     SysFreeString( str );
3893
3894     str = SysAllocString( szdl );
3895     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3896     ok( r == S_OK, "ret %08x\n", r );
3897     r = IXMLDOMNodeList_get_length( node_list, &len );
3898     ok( r == S_OK, "ret %08x\n", r );
3899     ok( len == 0, "len %d\n", len );
3900     IXMLDOMNodeList_Release( node_list );
3901     SysFreeString( str );
3902
3903     str = SysAllocString( szstr1 );
3904     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3905     ok( r == S_OK, "ret %08x\n", r );
3906     r = IXMLDOMNodeList_get_length( node_list, &len );
3907     ok( r == S_OK, "ret %08x\n", r );
3908     ok( len == 0, "len %d\n", len );
3909     IXMLDOMNodeList_Release( node_list );
3910     SysFreeString( str );
3911
3912     /* test for element */
3913     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3914     ok( r == S_OK, "ret %08x\n", r );
3915
3916     str = SysAllocString( szstar );
3917
3918     /* null arguments cases */
3919     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3920     ok( r == E_INVALIDARG, "ret %08x\n", r );
3921     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3922     ok( r == E_INVALIDARG, "ret %08x\n", r );
3923
3924     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3925     ok( r == S_OK, "ret %08x\n", r );
3926     r = IXMLDOMNodeList_get_length( node_list, &len );
3927     ok( r == S_OK, "ret %08x\n", r );
3928     ok( len == 5, "len %d\n", len );
3929     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3930     SysFreeString( str );
3931
3932     /* broken query BSTR */
3933     memcpy(&buff[2], szstar, sizeof(szstar));
3934     /* just a big length */
3935     *(DWORD*)buff = 0xf0f0;
3936     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3937     ok( r == S_OK, "ret %08x\n", r );
3938     r = IXMLDOMNodeList_get_length( node_list, &len );
3939     ok( r == S_OK, "ret %08x\n", r );
3940     ok( len == 5, "len %d\n", len );
3941     IXMLDOMNodeList_Release( node_list );
3942
3943     IXMLDOMElement_Release(elem);
3944
3945     IXMLDOMDocument_Release( doc );
3946
3947     free_bstrs();
3948 }
3949
3950 static void test_get_text(void)
3951 {
3952     HRESULT r;
3953     BSTR str;
3954     VARIANT_BOOL b;
3955     IXMLDOMDocument *doc;
3956     IXMLDOMNode *node, *node2, *node3;
3957     IXMLDOMNode *nodeRoot;
3958     IXMLDOMNodeList *node_list;
3959     IXMLDOMNamedNodeMap *node_map;
3960     LONG len;
3961
3962     doc = create_document(&IID_IXMLDOMDocument);
3963     if (!doc) return;
3964
3965     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3966     ok( r == S_OK, "loadXML failed\n");
3967     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3968
3969     str = SysAllocString( szbs );
3970     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3971     ok( r == S_OK, "ret %08x\n", r );
3972     SysFreeString(str);
3973
3974     /* Test to get all child node text. */
3975     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3976     ok( r == S_OK, "ret %08x\n", r );
3977     if(r == S_OK)
3978     {
3979         r = IXMLDOMNode_get_text( nodeRoot, &str );
3980         ok( r == S_OK, "ret %08x\n", r );
3981         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
3982         SysFreeString(str);
3983
3984         IXMLDOMNode_Release(nodeRoot);
3985     }
3986
3987     r = IXMLDOMNodeList_get_length( node_list, NULL );
3988     ok( r == E_INVALIDARG, "ret %08x\n", r );
3989
3990     r = IXMLDOMNodeList_get_length( node_list, &len );
3991     ok( r == S_OK, "ret %08x\n", r );
3992     ok( len == 1, "expect 1 got %d\n", len );
3993
3994     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3995     ok( r == E_INVALIDARG, "ret %08x\n", r );
3996
3997     r = IXMLDOMNodeList_nextNode( node_list, NULL );
3998     ok( r == E_INVALIDARG, "ret %08x\n", r );
3999
4000     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4001     ok( r == S_OK, "ret %08x\n", r );
4002     IXMLDOMNodeList_Release( node_list );
4003
4004     /* Invalid output parameter*/
4005     r = IXMLDOMNode_get_text( node, NULL );
4006     ok( r == E_INVALIDARG, "ret %08x\n", r );
4007
4008     r = IXMLDOMNode_get_text( node, &str );
4009     ok( r == S_OK, "ret %08x\n", r );
4010     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4011     SysFreeString(str);
4012
4013     r = IXMLDOMNode_get_attributes( node, &node_map );
4014     ok( r == S_OK, "ret %08x\n", r );
4015
4016     str = SysAllocString( szvr );
4017     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4018     ok( r == S_OK, "ret %08x\n", r );
4019     SysFreeString(str);
4020
4021     r = IXMLDOMNode_get_text( node2, &str );
4022     ok( r == S_OK, "ret %08x\n", r );
4023     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4024     SysFreeString(str);
4025
4026     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4027     ok( r == S_OK, "ret %08x\n", r );
4028
4029     r = IXMLDOMNode_get_text( node3, &str );
4030     ok( r == S_OK, "ret %08x\n", r );
4031     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4032     SysFreeString(str);
4033
4034
4035     IXMLDOMNode_Release( node3 );
4036     IXMLDOMNode_Release( node2 );
4037     IXMLDOMNamedNodeMap_Release( node_map );
4038     IXMLDOMNode_Release( node );
4039     IXMLDOMDocument_Release( doc );
4040
4041     free_bstrs();
4042 }
4043
4044 static void test_get_childNodes(void)
4045 {
4046     BSTR str;
4047     VARIANT_BOOL b;
4048     IXMLDOMDocument *doc;
4049     IXMLDOMElement *element;
4050     IXMLDOMNode *node, *node2;
4051     IXMLDOMNodeList *node_list, *node_list2;
4052     HRESULT hr;
4053     LONG len;
4054
4055     doc = create_document(&IID_IXMLDOMDocument);
4056     if (!doc) return;
4057
4058     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4059     EXPECT_HR(hr, S_OK);
4060     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4061
4062     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4063     EXPECT_HR(hr, S_OK);
4064
4065     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4066     EXPECT_HR(hr, S_OK);
4067
4068     hr = IXMLDOMNodeList_get_length( node_list, &len );
4069     EXPECT_HR(hr, S_OK);
4070     ok( len == 4, "len %d\n", len);
4071
4072     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4073     EXPECT_HR(hr, S_OK);
4074
4075     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4076     EXPECT_HR(hr, S_OK);
4077
4078     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4079     EXPECT_HR(hr, S_OK);
4080     ok( len == 0, "len %d\n", len);
4081
4082     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4083     EXPECT_HR(hr, S_FALSE);
4084
4085     IXMLDOMNodeList_Release( node_list2 );
4086     IXMLDOMNode_Release( node );
4087     IXMLDOMNodeList_Release( node_list );
4088     IXMLDOMElement_Release( element );
4089
4090     /* test for children of <?xml ..?> node */
4091     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4092     EXPECT_HR(hr, S_OK);
4093
4094     str = NULL;
4095     hr = IXMLDOMNode_get_nodeName(node, &str);
4096     EXPECT_HR(hr, S_OK);
4097     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4098     SysFreeString(str);
4099
4100     /* it returns empty but valid node list */
4101     node_list = (void*)0xdeadbeef;
4102     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4103     EXPECT_HR(hr, S_OK);
4104
4105     len = -1;
4106     hr = IXMLDOMNodeList_get_length(node_list, &len);
4107     EXPECT_HR(hr, S_OK);
4108     ok(len == 0, "got %d\n", len);
4109
4110     IXMLDOMNodeList_Release( node_list );
4111     IXMLDOMNode_Release(node);
4112
4113     IXMLDOMDocument_Release( doc );
4114     free_bstrs();
4115 }
4116
4117 static void test_get_firstChild(void)
4118 {
4119     static WCHAR xmlW[] = {'x','m','l',0};
4120     IXMLDOMDocument *doc;
4121     IXMLDOMNode *node;
4122     VARIANT_BOOL b;
4123     HRESULT r;
4124     BSTR str;
4125
4126     doc = create_document(&IID_IXMLDOMDocument);
4127     if (!doc) return;
4128
4129     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4130     ok( r == S_OK, "loadXML failed\n");
4131     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4132
4133     r = IXMLDOMDocument_get_firstChild( doc, &node );
4134     ok( r == S_OK, "ret %08x\n", r);
4135
4136     r = IXMLDOMNode_get_nodeName( node, &str );
4137     ok( r == S_OK, "ret %08x\n", r);
4138
4139     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4140
4141     SysFreeString(str);
4142     IXMLDOMNode_Release( node );
4143     IXMLDOMDocument_Release( doc );
4144
4145     free_bstrs();
4146 }
4147
4148 static void test_get_lastChild(void)
4149 {
4150     static WCHAR lcW[] = {'l','c',0};
4151     static WCHAR foW[] = {'f','o',0};
4152     IXMLDOMDocument *doc;
4153     IXMLDOMNode *node, *child;
4154     VARIANT_BOOL b;
4155     HRESULT r;
4156     BSTR str;
4157
4158     doc = create_document(&IID_IXMLDOMDocument);
4159     if (!doc) return;
4160
4161     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4162     ok( r == S_OK, "loadXML failed\n");
4163     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4164
4165     r = IXMLDOMDocument_get_lastChild( doc, &node );
4166     ok( r == S_OK, "ret %08x\n", r);
4167
4168     r = IXMLDOMNode_get_nodeName( node, &str );
4169     ok( r == S_OK, "ret %08x\n", r);
4170
4171     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4172     SysFreeString(str);
4173
4174     r = IXMLDOMNode_get_lastChild( node, &child );
4175     ok( r == S_OK, "ret %08x\n", r);
4176
4177     r = IXMLDOMNode_get_nodeName( child, &str );
4178     ok( r == S_OK, "ret %08x\n", r);
4179
4180     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4181     SysFreeString(str);
4182
4183     IXMLDOMNode_Release( child );
4184     IXMLDOMNode_Release( node );
4185     IXMLDOMDocument_Release( doc );
4186
4187     free_bstrs();
4188 }
4189
4190 static void test_removeChild(void)
4191 {
4192     HRESULT r;
4193     VARIANT_BOOL b;
4194     IXMLDOMDocument *doc;
4195     IXMLDOMElement *element, *lc_element;
4196     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4197     IXMLDOMNodeList *root_list, *fo_list;
4198
4199     doc = create_document(&IID_IXMLDOMDocument);
4200     if (!doc) return;
4201
4202     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4203     ok( r == S_OK, "loadXML failed\n");
4204     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4205
4206     r = IXMLDOMDocument_get_documentElement( doc, &element );
4207     ok( r == S_OK, "ret %08x\n", r);
4208     todo_wine EXPECT_REF(element, 2);
4209
4210     r = IXMLDOMElement_get_childNodes( element, &root_list );
4211     ok( r == S_OK, "ret %08x\n", r);
4212     EXPECT_REF(root_list, 1);
4213
4214     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4215     ok( r == S_OK, "ret %08x\n", r);
4216     EXPECT_REF(fo_node, 1);
4217
4218     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4219     ok( r == S_OK, "ret %08x\n", r);
4220     EXPECT_REF(fo_list, 1);
4221
4222     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4223     ok( r == S_OK, "ret %08x\n", r);
4224     EXPECT_REF(ba_node, 1);
4225
4226     /* invalid parameter: NULL ptr */
4227     removed_node = (void*)0xdeadbeef;
4228     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4229     ok( r == E_INVALIDARG, "ret %08x\n", r );
4230     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4231
4232     /* ba_node is a descendant of element, but not a direct child. */
4233     removed_node = (void*)0xdeadbeef;
4234     EXPECT_REF(ba_node, 1);
4235     EXPECT_CHILDREN(fo_node);
4236     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4237     ok( r == E_INVALIDARG, "ret %08x\n", r );
4238     ok( removed_node == NULL, "%p\n", removed_node );
4239     EXPECT_REF(ba_node, 1);
4240     EXPECT_CHILDREN(fo_node);
4241
4242     EXPECT_REF(ba_node, 1);
4243     EXPECT_REF(fo_node, 1);
4244     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4245     ok( r == S_OK, "ret %08x\n", r);
4246     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4247     EXPECT_REF(fo_node, 2);
4248     EXPECT_REF(ba_node, 1);
4249
4250     /* try removing already removed child */
4251     temp_node = (void*)0xdeadbeef;
4252     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4253     ok( r == E_INVALIDARG, "ret %08x\n", r);
4254     ok( temp_node == NULL, "%p\n", temp_node );
4255     IXMLDOMNode_Release( fo_node );
4256
4257     /* the removed node has no parent anymore */
4258     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4259     ok( r == S_FALSE, "ret %08x\n", r);
4260     ok( temp_node == NULL, "%p\n", temp_node );
4261
4262     IXMLDOMNode_Release( removed_node );
4263     IXMLDOMNode_Release( ba_node );
4264     IXMLDOMNodeList_Release( fo_list );
4265
4266     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4267     ok( r == S_OK, "ret %08x\n", r);
4268
4269     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4270     ok( r == S_OK, "ret %08x\n", r);
4271
4272     /* MS quirk: passing wrong interface pointer works, too */
4273     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4274     ok( r == S_OK, "ret %08x\n", r);
4275     IXMLDOMElement_Release( lc_element );
4276
4277     temp_node = (void*)0xdeadbeef;
4278     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4279     ok( r == S_FALSE, "ret %08x\n", r);
4280     ok( temp_node == NULL, "%p\n", temp_node );
4281
4282     IXMLDOMNode_Release( lc_node );
4283     IXMLDOMNodeList_Release( root_list );
4284     IXMLDOMElement_Release( element );
4285     IXMLDOMDocument_Release( doc );
4286
4287     free_bstrs();
4288 }
4289
4290 static void test_replaceChild(void)
4291 {
4292     HRESULT r;
4293     VARIANT_BOOL b;
4294     IXMLDOMDocument *doc;
4295     IXMLDOMElement *element, *ba_element;
4296     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4297     IXMLDOMNodeList *root_list, *fo_list;
4298     IUnknown * unk1, *unk2;
4299     LONG len;
4300
4301     doc = create_document(&IID_IXMLDOMDocument);
4302     if (!doc) return;
4303
4304     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4305     ok( r == S_OK, "loadXML failed\n");
4306     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4307
4308     r = IXMLDOMDocument_get_documentElement( doc, &element );
4309     ok( r == S_OK, "ret %08x\n", r);
4310
4311     r = IXMLDOMElement_get_childNodes( element, &root_list );
4312     ok( r == S_OK, "ret %08x\n", r);
4313
4314     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4315     ok( r == S_OK, "ret %08x\n", r);
4316
4317     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4318     ok( r == S_OK, "ret %08x\n", r);
4319
4320     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4321     ok( r == S_OK, "ret %08x\n", r);
4322
4323     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4324     ok( r == S_OK, "ret %08x\n", r);
4325
4326     IXMLDOMNodeList_Release( fo_list );
4327
4328     /* invalid parameter: NULL ptr for element to remove */
4329     removed_node = (void*)0xdeadbeef;
4330     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4331     ok( r == E_INVALIDARG, "ret %08x\n", r );
4332     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4333
4334     /* invalid parameter: NULL for replacement element. (Sic!) */
4335     removed_node = (void*)0xdeadbeef;
4336     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4337     ok( r == E_INVALIDARG, "ret %08x\n", r );
4338     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4339
4340     /* invalid parameter: OldNode is not a child */
4341     removed_node = (void*)0xdeadbeef;
4342     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4343     ok( r == E_INVALIDARG, "ret %08x\n", r );
4344     ok( removed_node == NULL, "%p\n", removed_node );
4345     IXMLDOMNode_Release( lc_node );
4346
4347     /* invalid parameter: would create loop */
4348     removed_node = (void*)0xdeadbeef;
4349     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4350     ok( r == E_FAIL, "ret %08x\n", r );
4351     ok( removed_node == NULL, "%p\n", removed_node );
4352
4353     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4354     ok( r == S_OK, "ret %08x\n", r );
4355
4356     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4357     ok( r == S_OK, "ret %08x\n", r );
4358
4359     /* ba_node and temp_node refer to the same node, yet they
4360        are different interface pointers */
4361     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4362     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4363     ok( r == S_OK, "ret %08x\n", r );
4364     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4365     ok( r == S_OK, "ret %08x\n", r );
4366     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4367
4368     IUnknown_Release( unk1 );
4369     IUnknown_Release( unk2 );
4370
4371     /* ba_node should have been removed from below fo_node */
4372     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4373     ok( r == S_OK, "ret %08x\n", r );
4374
4375     /* MS quirk: replaceChild also accepts elements instead of nodes */
4376     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4377     ok( r == S_OK, "ret %08x\n", r );
4378     EXPECT_REF(ba_element, 2);
4379
4380     removed_node = NULL;
4381     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4382     ok( r == S_OK, "ret %08x\n", r );
4383     ok( removed_node != NULL, "got %p\n", removed_node);
4384     EXPECT_REF(ba_element, 3);
4385     IXMLDOMElement_Release( ba_element );
4386
4387     r = IXMLDOMNodeList_get_length( fo_list, &len);
4388     ok( r == S_OK, "ret %08x\n", r );
4389     ok( len == 0, "len %d\n", len);
4390
4391     IXMLDOMNodeList_Release( fo_list );
4392
4393     IXMLDOMNode_Release(ba_node);
4394     IXMLDOMNode_Release(fo_node);
4395     IXMLDOMNode_Release(temp_node);
4396     IXMLDOMNodeList_Release( root_list );
4397     IXMLDOMElement_Release( element );
4398     IXMLDOMDocument_Release( doc );
4399
4400     free_bstrs();
4401 }
4402
4403 static void test_removeNamedItem(void)
4404 {
4405     IXMLDOMDocument *doc;
4406     IXMLDOMElement *element;
4407     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4408     IXMLDOMNodeList *root_list;
4409     IXMLDOMNamedNodeMap * pr_attrs;
4410     VARIANT_BOOL b;
4411     BSTR str;
4412     LONG len;
4413     HRESULT r;
4414
4415     doc = create_document(&IID_IXMLDOMDocument);
4416     if (!doc) return;
4417
4418     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4419     ok( r == S_OK, "loadXML failed\n");
4420     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4421
4422     r = IXMLDOMDocument_get_documentElement( doc, &element );
4423     ok( r == S_OK, "ret %08x\n", r);
4424
4425     r = IXMLDOMElement_get_childNodes( element, &root_list );
4426     ok( r == S_OK, "ret %08x\n", r);
4427
4428     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4429     ok( r == S_OK, "ret %08x\n", r);
4430
4431     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4432     ok( r == S_OK, "ret %08x\n", r);
4433
4434     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4435     ok( r == S_OK, "ret %08x\n", r);
4436     ok( len == 3, "length %d\n", len);
4437
4438     removed_node = (void*)0xdeadbeef;
4439     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4440     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4441     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4442
4443     removed_node = (void*)0xdeadbeef;
4444     str = SysAllocString(szvr);
4445     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4446     ok ( r == S_OK, "ret %08x\n", r);
4447
4448     removed_node2 = (void*)0xdeadbeef;
4449     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4450     ok ( r == S_FALSE, "ret %08x\n", r);
4451     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4452
4453     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4454     ok( r == S_OK, "ret %08x\n", r);
4455     ok( len == 2, "length %d\n", len);
4456
4457     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4458     ok ( r == S_OK, "ret %08x\n", r);
4459     IXMLDOMNode_Release(removed_node);
4460
4461     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4462     ok( r == S_OK, "ret %08x\n", r);
4463     ok( len == 3, "length %d\n", len);
4464
4465     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4466     ok ( r == S_OK, "ret %08x\n", r);
4467
4468     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4469     ok( r == S_OK, "ret %08x\n", r);
4470     ok( len == 2, "length %d\n", len);
4471
4472     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4473     ok ( r == S_FALSE, "ret %08x\n", r);
4474
4475     SysFreeString(str);
4476
4477     IXMLDOMNamedNodeMap_Release( pr_attrs );
4478     IXMLDOMNode_Release( pr_node );
4479     IXMLDOMNodeList_Release( root_list );
4480     IXMLDOMElement_Release( element );
4481     IXMLDOMDocument_Release( doc );
4482
4483     free_bstrs();
4484 }
4485
4486 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4487 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4488                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4489                                     DWORD expected2)
4490 {
4491     DWORD enabled, supported;
4492     HRESULT hr;
4493
4494     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4495     if (result == result2)
4496         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4497     else
4498         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4499            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4500
4501     supported = enabled = 0xCAFECAFE;
4502     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4503     ok(hr == S_OK, "ret %08x\n", hr );
4504     if (expected == expected2)
4505         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4506     else
4507         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4508            "Expected %08x, got %08x\n", expected2, enabled);
4509
4510     /* reset the safety options */
4511
4512     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4513             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4514             0);
4515     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4516
4517     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4518     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4519     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4520 }
4521
4522 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4523 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4524 {
4525     DWORD enabled = 0, supported = 0;
4526     HRESULT hr;
4527
4528     /* get */
4529     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4530     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4531     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4532     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4533
4534     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4535     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4536     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4537        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4538         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4539              "got %08x\n", supported);
4540     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4541
4542     /* set -- individual flags */
4543
4544     test_IObjectSafety_set(safety, S_OK, S_OK,
4545         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4546         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4547
4548     test_IObjectSafety_set(safety, S_OK, S_OK,
4549         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4550         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4551
4552     test_IObjectSafety_set(safety, S_OK, S_OK,
4553         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4554         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4555
4556     /* set INTERFACE_USES_DISPEX  */
4557
4558     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4559         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4560         0, 0);
4561
4562     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4563         INTERFACE_USES_DISPEX, 0,
4564         0, 0);
4565
4566     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4567         0, INTERFACE_USES_DISPEX,
4568         0, 0);
4569
4570     /* set option masking */
4571
4572     test_IObjectSafety_set(safety, S_OK, S_OK,
4573         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4574         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4575         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4576         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4577
4578     test_IObjectSafety_set(safety, S_OK, S_OK,
4579         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4580         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4581         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4582         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4583
4584     test_IObjectSafety_set(safety, S_OK, S_OK,
4585         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4586         INTERFACE_USES_SECURITY_MANAGER,
4587         0,
4588         0);
4589
4590     /* set -- inheriting previous settings */
4591
4592     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4593                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4594                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4595     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4596     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4597     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4598     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4599     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4600        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4601         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4602              "got %08x\n", supported);
4603
4604     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4605                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4606                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4607     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4608     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4609     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4610     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4611                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4612                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4613     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4614        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4615         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4616              "got %08x\n", supported);
4617 }
4618
4619 static void test_XMLHTTP(void)
4620 {
4621     static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
4622     static const WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
4623         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4624         'p','o','s','t','t','e','s','t','.','p','h','p',0};
4625     static const WCHAR xmltestW[] = {'h','t','t','p',':','/','/',
4626         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
4627         'x','m','l','t','e','s','t','.','x','m','l',0};
4628     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4629     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4630
4631     IXMLHttpRequest *xhr;
4632     IObjectSafety *safety;
4633     IObjectWithSite *obj_site, *obj_site2;
4634     BSTR bstrResponse, url;
4635     VARIANT dummy;
4636     VARIANT async;
4637     VARIANT varbody;
4638     LONG state, status, bound;
4639     IDispatch *event;
4640     void *ptr;
4641     HRESULT hr;
4642     HGLOBAL g;
4643
4644     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4645         &IID_IXMLHttpRequest, (void**)&xhr);
4646     if (FAILED(hr))
4647     {
4648         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4649         return;
4650     }
4651
4652     VariantInit(&dummy);
4653     V_VT(&dummy) = VT_ERROR;
4654     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4655     VariantInit(&async);
4656     V_VT(&async) = VT_BOOL;
4657     V_BOOL(&async) = VARIANT_FALSE;
4658     V_VT(&varbody) = VT_BSTR;
4659     V_BSTR(&varbody) = SysAllocString(wszBody);
4660
4661     url = SysAllocString(wszUrl);
4662
4663     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4664     EXPECT_HR(hr, S_OK);
4665
4666     hr = IXMLHttpRequest_abort(xhr);
4667     EXPECT_HR(hr, S_OK);
4668
4669     V_VT(&varbody) = VT_I2;
4670     V_I2(&varbody) = 1;
4671     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4672     EXPECT_HR(hr, E_PENDING);
4673     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4674     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4675
4676     V_VT(&varbody) = VT_I2;
4677     V_I2(&varbody) = 1;
4678     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4679     EXPECT_HR(hr, E_PENDING);
4680     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4681     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4682
4683     /* send before open */
4684     hr = IXMLHttpRequest_send(xhr, dummy);
4685     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4686
4687     /* initial status code */
4688     hr = IXMLHttpRequest_get_status(xhr, NULL);
4689     EXPECT_HR(hr, E_INVALIDARG);
4690
4691     status = 0xdeadbeef;
4692     hr = IXMLHttpRequest_get_status(xhr, &status);
4693     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4694     ok(status == 0xdeadbeef, "got %d\n", status);
4695
4696     /* invalid parameters */
4697     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4698     EXPECT_HR(hr, E_INVALIDARG);
4699
4700     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4701     EXPECT_HR(hr, E_INVALIDARG);
4702
4703     hr = IXMLHttpRequest_open(xhr, NULL, url, async, dummy, dummy);
4704     EXPECT_HR(hr, E_INVALIDARG);
4705
4706     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4707     EXPECT_HR(hr, E_INVALIDARG);
4708
4709     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4710     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4711
4712     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4713     EXPECT_HR(hr, E_INVALIDARG);
4714
4715     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4716     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4717
4718     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4719     EXPECT_HR(hr, E_INVALIDARG);
4720
4721     state = -1;
4722     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4723     EXPECT_HR(hr, S_OK);
4724     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4725
4726     event = create_dispevent();
4727
4728     EXPECT_REF(event, 1);
4729     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4730     EXPECT_HR(hr, S_OK);
4731     EXPECT_REF(event, 2);
4732
4733     g_unexpectedcall = g_expectedcall = 0;
4734
4735     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4736     EXPECT_HR(hr, S_OK);
4737
4738     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4739     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4740
4741     /* status code after ::open() */
4742     status = 0xdeadbeef;
4743     hr = IXMLHttpRequest_get_status(xhr, &status);
4744     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4745     ok(status == 0xdeadbeef, "got %d\n", status);
4746
4747     state = -1;
4748     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4749     EXPECT_HR(hr, S_OK);
4750     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4751
4752     hr = IXMLHttpRequest_abort(xhr);
4753     EXPECT_HR(hr, S_OK);
4754
4755     state = -1;
4756     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4757     EXPECT_HR(hr, S_OK);
4758     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4759         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4760
4761     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), url, async, dummy, dummy);
4762     EXPECT_HR(hr, S_OK);
4763
4764     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4765     EXPECT_HR(hr, S_OK);
4766
4767     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4768     EXPECT_HR(hr, E_INVALIDARG);
4769
4770     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4771     EXPECT_HR(hr, E_INVALIDARG);
4772
4773     SysFreeString(url);
4774
4775     hr = IXMLHttpRequest_send(xhr, varbody);
4776     if (hr == INET_E_RESOURCE_NOT_FOUND)
4777     {
4778         skip("No connection could be made with crossover.codeweavers.com\n");
4779         IXMLHttpRequest_Release(xhr);
4780         return;
4781     }
4782     EXPECT_HR(hr, S_OK);
4783
4784     /* status code after ::send() */
4785     status = 0xdeadbeef;
4786     hr = IXMLHttpRequest_get_status(xhr, &status);
4787     EXPECT_HR(hr, S_OK);
4788     ok(status == 200, "got %d\n", status);
4789
4790     /* another ::send() after completed request */
4791     hr = IXMLHttpRequest_send(xhr, varbody);
4792     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4793
4794     VariantClear(&varbody);
4795
4796     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4797     EXPECT_HR(hr, S_OK);
4798     /* the server currently returns "FAILED" because the Content-Type header is
4799      * not what the server expects */
4800     if(hr == S_OK)
4801     {
4802         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4803             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4804         SysFreeString(bstrResponse);
4805     }
4806
4807     /* GET request */
4808     url = SysAllocString(xmltestW);
4809
4810     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), url, async, dummy, dummy);
4811     EXPECT_HR(hr, S_OK);
4812
4813     V_VT(&varbody) = VT_EMPTY;
4814
4815     hr = IXMLHttpRequest_send(xhr, varbody);
4816     if (hr == INET_E_RESOURCE_NOT_FOUND)
4817     {
4818         skip("No connection could be made with crossover.codeweavers.com\n");
4819         IXMLHttpRequest_Release(xhr);
4820         return;
4821     }
4822     EXPECT_HR(hr, S_OK);
4823
4824     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4825     EXPECT_HR(hr, E_INVALIDARG);
4826
4827     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4828     EXPECT_HR(hr, S_OK);
4829     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4830         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4831     SysFreeString(bstrResponse);
4832
4833     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4834     EXPECT_HR(hr, E_INVALIDARG);
4835
4836     V_VT(&varbody) = VT_EMPTY;
4837     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4838     EXPECT_HR(hr, S_OK);
4839     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4840     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4841
4842     bound = -1;
4843     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4844     EXPECT_HR(hr, S_OK);
4845     ok(bound == 0, "got %d, expected zero bound\n", bound);
4846
4847     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4848     EXPECT_HR(hr, S_OK);
4849     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4850     SafeArrayUnaccessData(V_ARRAY(&varbody));
4851
4852     VariantClear(&varbody);
4853     SysFreeString(url);
4854
4855     /* get_responseStream */
4856     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
4857     EXPECT_HR(hr, E_INVALIDARG);
4858
4859     V_VT(&varbody) = VT_EMPTY;
4860     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4861     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
4862     EXPECT_HR(hr, S_OK);
4863     EXPECT_REF(V_UNKNOWN(&varbody), 1);
4864
4865     g = NULL;
4866     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
4867     EXPECT_HR(hr, S_OK);
4868     ok(g != NULL, "got %p\n", g);
4869
4870     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4871     EXPECT_HR(hr, S_OK);
4872     if(hr == S_OK)
4873     {
4874         test_IObjectSafety_common(safety);
4875         IObjectSafety_Release(safety);
4876     }
4877
4878     IDispatch_Release(event);
4879
4880     /* interaction with object site */
4881     EXPECT_REF(xhr, 1);
4882     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4883     EXPECT_HR(hr, S_OK);
4884 todo_wine {
4885     EXPECT_REF(xhr, 1);
4886     EXPECT_REF(obj_site, 1);
4887 }
4888
4889     IObjectWithSite_AddRef(obj_site);
4890 todo_wine {
4891     EXPECT_REF(obj_site, 2);
4892     EXPECT_REF(xhr, 1);
4893 }
4894     IObjectWithSite_Release(obj_site);
4895
4896     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
4897     EXPECT_HR(hr, S_OK);
4898 todo_wine {
4899     EXPECT_REF(xhr, 1);
4900     EXPECT_REF(obj_site, 1);
4901     EXPECT_REF(obj_site2, 1);
4902     ok(obj_site != obj_site2, "expected new instance\n");
4903 }
4904     SET_EXPECT(site_qi_IServiceProvider);
4905     SET_EXPECT(sp_queryservice_SID_SBindHost);
4906     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4907     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
4908     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
4909     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
4910
4911     /* calls to IHTMLDocument2 */
4912     SET_EXPECT(htmldoc2_get_all);
4913     SET_EXPECT(collection_get_length);
4914     SET_EXPECT(htmldoc2_get_url);
4915
4916     SET_EXPECT(site_qi_IXMLDOMDocument);
4917     SET_EXPECT(site_qi_IOleClientSite);
4918
4919     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
4920     EXPECT_HR(hr, S_OK);
4921
4922 todo_wine{
4923     CHECK_CALLED(site_qi_IServiceProvider);
4924
4925     CHECK_CALLED(sp_queryservice_SID_SBindHost);
4926     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4927     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
4928     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
4929     /* this one isn't very reliable
4930     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
4931
4932     CHECK_CALLED(htmldoc2_get_all);
4933     CHECK_CALLED(collection_get_length);
4934     CHECK_CALLED(htmldoc2_get_url);
4935
4936     CHECK_CALLED(site_qi_IXMLDOMDocument);
4937     CHECK_CALLED(site_qi_IOleClientSite);
4938 }
4939     IObjectWithSite_Release(obj_site);
4940
4941     todo_wine EXPECT_REF(xhr, 1);
4942     IXMLHttpRequest_Release(xhr);
4943
4944     /* still works after request is released */
4945     SET_EXPECT(site_qi_IServiceProvider);
4946
4947     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
4948     EXPECT_HR(hr, S_OK);
4949     IObjectWithSite_Release(obj_site2);
4950
4951     free_bstrs();
4952 }
4953
4954 static void test_IXMLDOMDocument2(void)
4955 {
4956     static const WCHAR emptyW[] = {0};
4957     IXMLDOMDocument2 *doc2, *dtddoc2;
4958     IXMLDOMDocument *doc;
4959     IXMLDOMParseError* err;
4960     IDispatchEx *dispex;
4961     VARIANT_BOOL b;
4962     VARIANT var;
4963     HRESULT r;
4964     LONG res;
4965
4966     doc = create_document(&IID_IXMLDOMDocument);
4967     if (!doc) return;
4968
4969     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4970     if (!dtddoc2)
4971     {
4972         IXMLDOMDocument_Release(doc);
4973         return;
4974     }
4975
4976     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4977     ok( r == S_OK, "ret %08x\n", r );
4978     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4979
4980     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4981     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4982     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4983
4984     err = NULL;
4985     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4986     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4987     ok(err != NULL, "expected a pointer\n");
4988     if (err)
4989     {
4990         res = 0;
4991         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4992         /* XML_E_NOTWF */
4993         ok(res == E_XML_NOTWF, "got %08x\n", res);
4994         IXMLDOMParseError_Release(err);
4995     }
4996
4997     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
4998     ok( r == S_OK, "loadXML failed\n");
4999     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5000
5001     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
5002     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5003
5004     err = NULL;
5005     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5006     ok(err != NULL, "expected a pointer\n");
5007     if (err)
5008     {
5009         res = 0;
5010         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5011         /* XML_E_NODTD */
5012         ok(res == E_XML_NODTD, "got %08x\n", res);
5013         IXMLDOMParseError_Release(err);
5014     }
5015
5016     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5017     ok( r == S_OK, "ret %08x\n", r );
5018     if(r == S_OK)
5019     {
5020         IDispatchEx_Release(dispex);
5021     }
5022
5023     /* we will check if the variant got cleared */
5024     IXMLDOMDocument2_AddRef(doc2);
5025     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5026
5027     V_VT(&var) = VT_UNKNOWN;
5028     V_UNKNOWN(&var) = (IUnknown *)doc2;
5029
5030     /* invalid calls */
5031     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5032     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5033     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5034
5035     /* valid call */
5036     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5037     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5038     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5039     V_VT(&var) = VT_R4;
5040
5041     /* the variant didn't get cleared*/
5042     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5043
5044     /* setProperty tests */
5045     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5046     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5047     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5048     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5049     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5050     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5051
5052     V_VT(&var) = VT_BSTR;
5053     V_BSTR(&var) = SysAllocString(emptyW);
5054     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5055     ok(r == S_OK, "got 0x%08x\n", r);
5056     VariantClear(&var);
5057
5058     V_VT(&var) = VT_I2;
5059     V_I2(&var) = 0;
5060     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5061     ok(r == E_FAIL, "got 0x%08x\n", r);
5062
5063     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5064     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5065     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5066     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5067
5068     IXMLDOMDocument2_Release( doc2 );
5069     IXMLDOMDocument_Release( doc );
5070
5071     /* DTD validation */
5072     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5073     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5074     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5075     err = NULL;
5076     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5077     ok(err != NULL, "expected pointer\n");
5078     if (err)
5079     {
5080         res = 0;
5081         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5082         ok(res == 0, "got %08x\n", res);
5083         IXMLDOMParseError_Release(err);
5084     }
5085
5086     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5087     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5088     err = NULL;
5089     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5090     ok(err != NULL, "expected pointer\n");
5091     if (err)
5092     {
5093         res = 0;
5094         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5095         /* XML_ELEMENT_UNDECLARED */
5096         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5097         IXMLDOMParseError_Release(err);
5098     }
5099
5100     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5101     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5102     err = NULL;
5103     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5104     ok(err != NULL, "expected pointer\n");
5105     if (err)
5106     {
5107         res = 0;
5108         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5109         /* XML_ELEMENT_ID_NOT_FOUND */
5110         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5111         IXMLDOMParseError_Release(err);
5112     }
5113
5114     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5115     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5116     err = NULL;
5117     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5118     ok(err != NULL, "expected pointer\n");
5119     if (err)
5120     {
5121         res = 0;
5122         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5123         /* XML_EMPTY_NOT_ALLOWED */
5124         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5125         IXMLDOMParseError_Release(err);
5126     }
5127
5128     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5129     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5130     err = NULL;
5131     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5132     ok(err != NULL, "expected pointer\n");
5133     if (err)
5134     {
5135         res = 0;
5136         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5137         /* XML_ROOT_NAME_MISMATCH */
5138         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5139         IXMLDOMParseError_Release(err);
5140     }
5141
5142     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5143     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5144     err = NULL;
5145     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5146     ok(err != NULL, "expected pointer\n");
5147     if (err)
5148     {
5149         res = 0;
5150         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5151         /* XML_INVALID_CONTENT */
5152         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5153         IXMLDOMParseError_Release(err);
5154     }
5155
5156     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5157     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5158     err = NULL;
5159     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5160     ok(err != NULL, "expected pointer\n");
5161     if (err)
5162     {
5163         res = 0;
5164         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5165         /* XML_ATTRIBUTE_NOT_DEFINED */
5166         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5167         IXMLDOMParseError_Release(err);
5168     }
5169
5170     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5171     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5172     err = NULL;
5173     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5174     ok(err != NULL, "expected pointer\n");
5175     if (err)
5176     {
5177         res = 0;
5178         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5179         /* XML_ATTRIBUTE_FIXED */
5180         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5181         IXMLDOMParseError_Release(err);
5182     }
5183
5184     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5185     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5186     err = NULL;
5187     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5188     ok(err != NULL, "expected pointer\n");
5189     if (err)
5190     {
5191         res = 0;
5192         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5193         /* XML_ATTRIBUTE_VALUE */
5194         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5195         IXMLDOMParseError_Release(err);
5196     }
5197
5198     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5199     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5200     err = NULL;
5201     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5202     ok(err != NULL, "expected pointer\n");
5203     if (err)
5204     {
5205         res = 0;
5206         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5207         /* XML_ILLEGAL_TEXT */
5208         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5209         IXMLDOMParseError_Release(err);
5210     }
5211
5212     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5213     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5214     err = NULL;
5215     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5216     ok(err != NULL, "expected pointer\n");
5217     if (err)
5218     {
5219         res = 0;
5220         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5221         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5222         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5223         IXMLDOMParseError_Release(err);
5224     }
5225
5226     IXMLDOMDocument2_Release( dtddoc2 );
5227     free_bstrs();
5228 }
5229
5230 #define helper_ole_check(expr) { \
5231     HRESULT r = expr; \
5232     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5233 }
5234
5235 #define helper_expect_list_and_release(list, expstr) { \
5236     char *str = list_to_string(list); \
5237     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5238     if (list) IXMLDOMNodeList_Release(list); \
5239 }
5240
5241 #define helper_expect_bstr_and_release(bstr, str) { \
5242     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5243        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5244     SysFreeString(bstr); \
5245 }
5246
5247 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5248 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5249 {
5250     IXMLDOMNode *node1, *node2;
5251     IXMLDOMNodeList *list;
5252     BSTR bstr;
5253
5254     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5255     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5256     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5257     helper_ole_check(IXMLDOMNodeList_reset(list));
5258     helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
5259
5260     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5261     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");
5262     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5263     if (str)
5264     {
5265         helper_expect_bstr_and_release(bstr, str);
5266     }
5267     else
5268     {
5269         helper_expect_bstr_and_release(bstr, "This is a description.");
5270     }
5271     IXMLDOMNode_Release(node1);
5272
5273     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5274     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");
5275     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5276     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5277     IXMLDOMNode_Release(node2);
5278 }
5279
5280 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5281 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5282 {
5283     IXMLDOMNode *node1, *node2;
5284     IXMLDOMNodeList *list;
5285     BSTR bstr;
5286
5287     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5288     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5289     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5290     helper_ole_check(IXMLDOMNodeList_reset(list));
5291     helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
5292
5293     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5294     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");
5295     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5296     if (str)
5297     {
5298         helper_expect_bstr_and_release(bstr, str);
5299     }
5300     else
5301     {
5302         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5303     }
5304     IXMLDOMNode_Release(node1);
5305
5306     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5307     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");
5308     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5309     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5310     IXMLDOMNode_Release(node2);
5311 }
5312
5313 static void test_whitespace(void)
5314 {
5315     VARIANT_BOOL b;
5316     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5317
5318     doc1 = create_document(&IID_IXMLDOMDocument2);
5319     doc2 = create_document(&IID_IXMLDOMDocument2);
5320     if (!doc1 || !doc2) return;
5321
5322     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5323     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5324     ok(b == VARIANT_FALSE, "expected false\n");
5325     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5326     ok(b == VARIANT_TRUE, "expected true\n");
5327
5328     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5329     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5330     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5331     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5332
5333     /* switch to XPath */
5334     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5335     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5336
5337     check_ws_ignored(doc1, NULL);
5338     check_ws_preserved(doc2, NULL);
5339
5340     /* new instances copy the property */
5341     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5342     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5343
5344     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5345     ok(b == VARIANT_FALSE, "expected false\n");
5346     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5347     ok(b == VARIANT_TRUE, "expected true\n");
5348
5349     check_ws_ignored(doc3, NULL);
5350     check_ws_preserved(doc4, NULL);
5351
5352     /* setting after loading xml affects trimming of leading/trailing ws only */
5353     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5354     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5355
5356     /* the trailing "\n            " isn't there, because it was ws-only node */
5357     check_ws_ignored(doc1, "\n                This is a description. ");
5358     check_ws_preserved(doc2, "This is a description.");
5359
5360     /* it takes effect on reload */
5361     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5362     ok(b == VARIANT_TRUE, "expected true\n");
5363     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5364     ok(b == VARIANT_FALSE, "expected false\n");
5365
5366     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5367     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5368     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5369     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5370
5371     check_ws_preserved(doc1, NULL);
5372     check_ws_ignored(doc2, NULL);
5373
5374     /* other instances follow suit */
5375     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5376     ok(b == VARIANT_TRUE, "expected true\n");
5377     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5378     ok(b == VARIANT_FALSE, "expected false\n");
5379
5380     check_ws_preserved(doc3, NULL);
5381     check_ws_ignored(doc4, NULL);
5382
5383     IXMLDOMDocument_Release(doc1);
5384     IXMLDOMDocument_Release(doc2);
5385     IXMLDOMDocument_Release(doc3);
5386     IXMLDOMDocument_Release(doc4);
5387     free_bstrs();
5388 }
5389
5390 static void test_XPath(void)
5391 {
5392     VARIANT var;
5393     VARIANT_BOOL b;
5394     IXMLDOMDocument2 *doc;
5395     IXMLDOMDocument *doc2;
5396     IXMLDOMNode *rootNode;
5397     IXMLDOMNode *elem1Node;
5398     IXMLDOMNode *node;
5399     IXMLDOMNodeList *list;
5400     IXMLDOMElement *elem;
5401     IXMLDOMAttribute *attr;
5402     HRESULT hr;
5403     BSTR str;
5404
5405     doc = create_document(&IID_IXMLDOMDocument2);
5406     if (!doc) return;
5407
5408     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
5409     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5410
5411     /* switch to XPath */
5412     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5413
5414     /* some simple queries*/
5415     EXPECT_REF(doc, 1);
5416     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5417     EXPECT_HR(hr, S_OK);
5418     EXPECT_REF(doc, 1);
5419     EXPECT_LIST_LEN(list, 1);
5420
5421     EXPECT_REF(list, 1);
5422     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5423     EXPECT_HR(hr, S_OK);
5424     EXPECT_REF(list, 1);
5425     EXPECT_REF(rootNode, 1);
5426
5427     hr = IXMLDOMNodeList_reset(list);
5428     EXPECT_HR(hr, S_OK);
5429     expect_list_and_release(list, "E2.D1");
5430
5431     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5432     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5433
5434     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5435     expect_list_and_release(list, "E3.E2.E2.D1");
5436
5437     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5438     /* using get_item for query results advances the position */
5439     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5440     expect_node(node, "E2.E2.D1");
5441     IXMLDOMNode_Release(node);
5442     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5443     expect_node(node, "E4.E2.D1");
5444     IXMLDOMNode_Release(node);
5445     ole_check(IXMLDOMNodeList_reset(list));
5446     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5447
5448     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5449     expect_list_and_release(list, "E2.D1");
5450
5451     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5452     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5453     ole_check(IXMLDOMNodeList_reset(list));
5454     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5455
5456     /* select an attribute */
5457     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5458     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5459
5460     /* would evaluate to a number */
5461     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5462     /* would evaluate to a boolean */
5463     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5464     /* would evaluate to a string */
5465     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5466
5467     /* no results */
5468     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5469     expect_list_and_release(list, "");
5470     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5471     expect_list_and_release(list, "");
5472     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5473     expect_list_and_release(list, "");
5474     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5475     expect_list_and_release(list, "");
5476
5477     /* foo undeclared in document node */
5478     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5479     /* undeclared in <root> node */
5480     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5481     /* undeclared in <elem> node */
5482     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5483     /* but this trick can be used */
5484     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5485     expect_list_and_release(list, "E3.E4.E2.D1");
5486
5487     /* it has to be declared in SelectionNamespaces */
5488     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5489         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5490
5491     /* now the namespace can be used */
5492     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5493     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5494     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5495     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5496     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5497     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5498     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5499     expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
5500
5501     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5502     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5503         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5504
5505     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5506
5507     VariantInit(&var);
5508     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5509     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5510     if (V_VT(&var) == VT_BSTR)
5511         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5512
5513     /* extra attributes - same thing*/
5514     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5515         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5516     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5517
5518     IXMLDOMNode_Release(rootNode);
5519     IXMLDOMNode_Release(elem1Node);
5520
5521     /* alter document with already built list */
5522     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5523     EXPECT_HR(hr, S_OK);
5524     EXPECT_LIST_LEN(list, 1);
5525
5526     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5527     EXPECT_HR(hr, S_OK);
5528     EXPECT_REF(rootNode, 1);
5529     EXPECT_REF(doc, 1);
5530
5531     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5532     EXPECT_HR(hr, S_OK);
5533     IXMLDOMNode_Release(rootNode);
5534
5535     EXPECT_LIST_LEN(list, 1);
5536
5537     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5538     EXPECT_HR(hr, S_OK);
5539     EXPECT_REF(rootNode, 1);
5540
5541     IXMLDOMNodeList_Release(list);
5542
5543     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5544     EXPECT_HR(hr, S_OK);
5545     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5546     SysFreeString(str);
5547     IXMLDOMNode_Release(rootNode);
5548
5549     /* alter node from list and get it another time */
5550     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5551     EXPECT_HR(hr, S_OK);
5552     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5553
5554     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5555     EXPECT_HR(hr, S_OK);
5556     EXPECT_LIST_LEN(list, 1);
5557
5558     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5559     EXPECT_HR(hr, S_OK);
5560
5561     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5562     EXPECT_HR(hr, S_OK);
5563
5564     V_VT(&var) = VT_I2;
5565     V_I2(&var) = 1;
5566     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5567     EXPECT_HR(hr, S_OK);
5568     IXMLDOMElement_Release(elem);
5569     IXMLDOMNode_Release(rootNode);
5570
5571     /* now check attribute to be present */
5572     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5573     EXPECT_HR(hr, S_OK);
5574
5575     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5576     EXPECT_HR(hr, S_OK);
5577
5578     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5579     EXPECT_HR(hr, S_OK);
5580     IXMLDOMAttribute_Release(attr);
5581
5582     IXMLDOMElement_Release(elem);
5583     IXMLDOMNode_Release(rootNode);
5584
5585     /* and now check for attribute in original document */
5586     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5587     EXPECT_HR(hr, S_OK);
5588
5589     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5590     EXPECT_HR(hr, S_OK);
5591     IXMLDOMAttribute_Release(attr);
5592
5593     IXMLDOMElement_Release(elem);
5594
5595     /* attach node from list to another document */
5596     doc2 = create_document(&IID_IXMLDOMDocument);
5597
5598     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5599     EXPECT_HR(hr, S_OK);
5600     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5601
5602     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5603     EXPECT_HR(hr, S_OK);
5604     EXPECT_LIST_LEN(list, 1);
5605
5606     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5607     EXPECT_HR(hr, S_OK);
5608     EXPECT_REF(rootNode, 1);
5609
5610     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5611     EXPECT_HR(hr, S_OK);
5612     EXPECT_REF(rootNode, 1);
5613     EXPECT_REF(doc2, 1);
5614     EXPECT_REF(list, 1);
5615
5616     EXPECT_LIST_LEN(list, 1);
5617
5618     IXMLDOMNode_Release(rootNode);
5619     IXMLDOMNodeList_Release(list);
5620     IXMLDOMDocument_Release(doc2);
5621
5622     IXMLDOMDocument2_Release(doc);
5623     free_bstrs();
5624 }
5625
5626 static void test_cloneNode(void )
5627 {
5628     IXMLDOMDocument *doc, *doc2;
5629     VARIANT_BOOL b;
5630     IXMLDOMNodeList *pList;
5631     IXMLDOMNamedNodeMap *mapAttr;
5632     LONG length, length1;
5633     LONG attr_cnt, attr_cnt1;
5634     IXMLDOMNode *node;
5635     IXMLDOMNode *node_clone;
5636     IXMLDOMNode *node_first;
5637     HRESULT hr;
5638
5639     doc = create_document(&IID_IXMLDOMDocument);
5640     if (!doc) return;
5641
5642     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5643     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5644
5645     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5646     ok( hr == S_OK, "ret %08x\n", hr );
5647     ok( node != NULL, "node %p\n", node );
5648
5649     /* Check invalid parameter */
5650     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5651     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5652
5653     /* All Children */
5654     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5655     ok( hr == S_OK, "ret %08x\n", hr );
5656     ok( node_clone != NULL, "node %p\n", node );
5657
5658     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5659     ok( hr == S_OK, "ret %08x\n", hr );
5660     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5661     ok( hr == S_OK, "ret %08x\n", hr );
5662     IXMLDOMDocument_Release(doc2);
5663     IXMLDOMNode_Release(node_first);
5664
5665     hr = IXMLDOMNode_get_childNodes(node, &pList);
5666     ok( hr == S_OK, "ret %08x\n", hr );
5667     length = 0;
5668     hr = IXMLDOMNodeList_get_length(pList, &length);
5669     ok( hr == S_OK, "ret %08x\n", hr );
5670     ok(length == 1, "got %d\n", length);
5671     IXMLDOMNodeList_Release(pList);
5672
5673     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5674     ok( hr == S_OK, "ret %08x\n", hr );
5675     attr_cnt = 0;
5676     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5677     ok( hr == S_OK, "ret %08x\n", hr );
5678     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5679     IXMLDOMNamedNodeMap_Release(mapAttr);
5680
5681     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5682     ok( hr == S_OK, "ret %08x\n", hr );
5683     length1 = 0;
5684     hr = IXMLDOMNodeList_get_length(pList, &length1);
5685     ok(length1 == 1, "got %d\n", length1);
5686     ok( hr == S_OK, "ret %08x\n", hr );
5687     IXMLDOMNodeList_Release(pList);
5688
5689     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5690     ok( hr == S_OK, "ret %08x\n", hr );
5691     attr_cnt1 = 0;
5692     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5693     ok( hr == S_OK, "ret %08x\n", hr );
5694     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5695     IXMLDOMNamedNodeMap_Release(mapAttr);
5696
5697     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5698     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5699     IXMLDOMNode_Release(node_clone);
5700
5701     /* No Children */
5702     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5703     ok( hr == S_OK, "ret %08x\n", hr );
5704     ok( node_clone != NULL, "node %p\n", node );
5705
5706     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5707     ok(hr == S_FALSE, "ret %08x\n", hr );
5708
5709     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5710     ok(hr == S_OK, "ret %08x\n", hr );
5711     hr = IXMLDOMNodeList_get_length(pList, &length1);
5712     ok(hr == S_OK, "ret %08x\n", hr );
5713     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5714     IXMLDOMNodeList_Release(pList);
5715
5716     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5717     ok(hr == S_OK, "ret %08x\n", hr );
5718     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5719     ok(hr == S_OK, "ret %08x\n", hr );
5720     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5721     IXMLDOMNamedNodeMap_Release(mapAttr);
5722
5723     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5724     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5725     IXMLDOMNode_Release(node_clone);
5726
5727     IXMLDOMNode_Release(node);
5728     IXMLDOMDocument_Release(doc);
5729     free_bstrs();
5730 }
5731
5732 static void test_xmlTypes(void)
5733 {
5734     IXMLDOMDocument *doc;
5735     IXMLDOMElement *pRoot;
5736     HRESULT hr;
5737     IXMLDOMComment *pComment;
5738     IXMLDOMElement *pElement;
5739     IXMLDOMAttribute *pAttribute;
5740     IXMLDOMNamedNodeMap *pAttribs;
5741     IXMLDOMCDATASection *pCDataSec;
5742     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5743     IXMLDOMDocumentFragment *pDocFrag = NULL;
5744     IXMLDOMEntityReference *pEntityRef = NULL;
5745     BSTR str;
5746     IXMLDOMNode *pNextChild;
5747     VARIANT v;
5748     LONG len = 0;
5749
5750     doc = create_document(&IID_IXMLDOMDocument);
5751     if (!doc) return;
5752
5753     pNextChild = (void*)0xdeadbeef;
5754     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5755     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5756
5757     pNextChild = (void*)0xdeadbeef;
5758     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5759     ok(hr == S_FALSE, "ret %08x\n", hr );
5760     ok(pNextChild == NULL, "pDocChild not NULL\n");
5761
5762     /* test previous Sibling */
5763     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5764     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5765
5766     pNextChild = (void*)0xdeadbeef;
5767     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5768     ok(hr == S_FALSE, "ret %08x\n", hr );
5769     ok(pNextChild == NULL, "pNextChild not NULL\n");
5770
5771     /* test get_dataType */
5772     V_VT(&v) = VT_EMPTY;
5773     hr = IXMLDOMDocument_get_dataType(doc, &v);
5774     ok(hr == S_FALSE, "ret %08x\n", hr );
5775     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5776     VariantClear(&v);
5777
5778     /* test implementation */
5779     hr = IXMLDOMDocument_get_implementation(doc, NULL);
5780     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5781
5782     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5783     ok(hr == S_OK, "ret %08x\n", hr );
5784     if(hr == S_OK)
5785     {
5786         VARIANT_BOOL hasFeature = VARIANT_TRUE;
5787         BSTR sEmpty = SysAllocStringLen(NULL, 0);
5788
5789         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5790         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5791
5792         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5793         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5794
5795         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5796         ok(hr == S_OK, "ret %08x\n", hr );
5797         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5798
5799         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5800         ok(hr == S_OK, "ret %08x\n", hr );
5801         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5802
5803         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5804         ok(hr == S_OK, "ret %08x\n", hr );
5805         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5806
5807         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5808         ok(hr == S_OK, "ret %08x\n", hr );
5809         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5810
5811         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5812         ok(hr == S_OK, "ret %08x\n", hr );
5813         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5814
5815         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5816         ok(hr == S_OK, "ret %08x\n", hr );
5817         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5818
5819         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5820         ok(hr == S_OK, "ret %08x\n", hr );
5821         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5822
5823         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5824         ok(hr == S_OK, "ret %08x\n", hr );
5825         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5826
5827         SysFreeString(sEmpty);
5828         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5829     }
5830
5831     pRoot = (IXMLDOMElement*)0x1;
5832     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5833     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5834     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5835
5836     pRoot = (IXMLDOMElement*)0x1;
5837     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5838     ok(hr == E_FAIL, "ret %08x\n", hr );
5839     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5840
5841     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5842     ok(hr == S_OK, "ret %08x\n", hr );
5843     if(hr == S_OK)
5844     {
5845         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5846         ok(hr == S_OK, "ret %08x\n", hr );
5847         if(hr == S_OK)
5848         {
5849             /* Comment */
5850             str = SysAllocString(szComment);
5851             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5852             SysFreeString(str);
5853             ok(hr == S_OK, "ret %08x\n", hr );
5854             if(hr == S_OK)
5855             {
5856                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5857                 ok(hr == S_OK, "ret %08x\n", hr );
5858
5859                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5860                 ok(hr == S_OK, "ret %08x\n", hr );
5861                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
5862                 SysFreeString(str);
5863
5864                 hr = IXMLDOMComment_get_xml(pComment, &str);
5865                 ok(hr == S_OK, "ret %08x\n", hr );
5866                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
5867                 SysFreeString(str);
5868
5869                 /* put data Tests */
5870                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5871                 ok(hr == S_OK, "ret %08x\n", hr );
5872
5873                 /* get data Tests */
5874                 hr = IXMLDOMComment_get_data(pComment, &str);
5875                 ok(hr == S_OK, "ret %08x\n", hr );
5876                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
5877                 SysFreeString(str);
5878
5879                 /* Confirm XML text is good */
5880                 hr = IXMLDOMComment_get_xml(pComment, &str);
5881                 ok(hr == S_OK, "ret %08x\n", hr );
5882                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
5883                 SysFreeString(str);
5884
5885                 /* Confirm we get the put_data Text back */
5886                 hr = IXMLDOMComment_get_text(pComment, &str);
5887                 ok(hr == S_OK, "ret %08x\n", hr );
5888                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
5889                 SysFreeString(str);
5890
5891                 /* test length property */
5892                 hr = IXMLDOMComment_get_length(pComment, &len);
5893                 ok(hr == S_OK, "ret %08x\n", hr );
5894                 ok(len == 21, "expected 21 got %d\n", len);
5895
5896                 /* test substringData */
5897                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5898                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5899
5900                 /* test substringData - Invalid offset */
5901                 str = (BSTR)&szElement;
5902                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5903                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5904                 ok( str == NULL, "incorrect string\n");
5905
5906                 /* test substringData - Invalid offset */
5907                 str = (BSTR)&szElement;
5908                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5909                 ok(hr == S_FALSE, "ret %08x\n", hr );
5910                 ok( str == NULL, "incorrect string\n");
5911
5912                 /* test substringData - Invalid size */
5913                 str = (BSTR)&szElement;
5914                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5915                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5916                 ok( str == NULL, "incorrect string\n");
5917
5918                 /* test substringData - Invalid size */
5919                 str = (BSTR)&szElement;
5920                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5921                 ok(hr == S_FALSE, "ret %08x\n", hr );
5922                 ok( str == NULL, "incorrect string\n");
5923
5924                 /* test substringData - Start of string */
5925                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5926                 ok(hr == S_OK, "ret %08x\n", hr );
5927                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5928                 SysFreeString(str);
5929
5930                 /* test substringData - Middle of string */
5931                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5932                 ok(hr == S_OK, "ret %08x\n", hr );
5933                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5934                 SysFreeString(str);
5935
5936                 /* test substringData - End of string */
5937                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5938                 ok(hr == S_OK, "ret %08x\n", hr );
5939                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5940                 SysFreeString(str);
5941
5942                 /* test appendData */
5943                 hr = IXMLDOMComment_appendData(pComment, NULL);
5944                 ok(hr == S_OK, "ret %08x\n", hr );
5945
5946                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5947                 ok(hr == S_OK, "ret %08x\n", hr );
5948
5949                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5950                 ok(hr == S_OK, "ret %08x\n", hr );
5951
5952                 hr = IXMLDOMComment_get_text(pComment, &str);
5953                 ok(hr == S_OK, "ret %08x\n", hr );
5954                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5955                 SysFreeString(str);
5956
5957                 /* test insertData */
5958                 str = SysAllocStringLen(NULL, 0);
5959                 hr = IXMLDOMComment_insertData(pComment, -1, str);
5960                 ok(hr == S_OK, "ret %08x\n", hr );
5961
5962                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5963                 ok(hr == S_OK, "ret %08x\n", hr );
5964
5965                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5966                 ok(hr == S_OK, "ret %08x\n", hr );
5967
5968                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5969                 ok(hr == S_OK, "ret %08x\n", hr );
5970
5971                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5972                 ok(hr == S_OK, "ret %08x\n", hr );
5973
5974                 hr = IXMLDOMComment_insertData(pComment, 0, str);
5975                 ok(hr == S_OK, "ret %08x\n", hr );
5976                 SysFreeString(str);
5977
5978                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5979                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5980
5981                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5982                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5983
5984                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5985                 ok(hr == S_OK, "ret %08x\n", hr );
5986
5987                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5988                 ok(hr == S_OK, "ret %08x\n", hr );
5989
5990                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5991                 ok(hr == S_OK, "ret %08x\n", hr );
5992
5993                 hr = IXMLDOMComment_get_text(pComment, &str);
5994                 ok(hr == S_OK, "ret %08x\n", hr );
5995                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5996                 SysFreeString(str);
5997
5998                 /* delete data */
5999                 /* invalid arguments */
6000                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6001                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6002
6003                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6004                 ok(hr == S_OK, "ret %08x\n", hr );
6005
6006                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6007                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6008
6009                 hr = IXMLDOMComment_get_length(pComment, &len);
6010                 ok(hr == S_OK, "ret %08x\n", hr );
6011                 ok(len == 43, "expected 43 got %d\n", len);
6012
6013                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6014                 ok(hr == S_OK, "ret %08x\n", hr );
6015
6016                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6017                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6018
6019                 /* delete from start */
6020                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6021                 ok(hr == S_OK, "ret %08x\n", hr );
6022
6023                 hr = IXMLDOMComment_get_length(pComment, &len);
6024                 ok(hr == S_OK, "ret %08x\n", hr );
6025                 ok(len == 38, "expected 38 got %d\n", len);
6026
6027                 hr = IXMLDOMComment_get_text(pComment, &str);
6028                 ok(hr == S_OK, "ret %08x\n", hr );
6029                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6030                 SysFreeString(str);
6031
6032                 /* delete from end */
6033                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6034                 ok(hr == S_OK, "ret %08x\n", hr );
6035
6036                 hr = IXMLDOMComment_get_length(pComment, &len);
6037                 ok(hr == S_OK, "ret %08x\n", hr );
6038                 ok(len == 35, "expected 35 got %d\n", len);
6039
6040                 hr = IXMLDOMComment_get_text(pComment, &str);
6041                 ok(hr == S_OK, "ret %08x\n", hr );
6042                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6043                 SysFreeString(str);
6044
6045                 /* delete from inside */
6046                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6047                 ok(hr == S_OK, "ret %08x\n", hr );
6048
6049                 hr = IXMLDOMComment_get_length(pComment, &len);
6050                 ok(hr == S_OK, "ret %08x\n", hr );
6051                 ok(len == 2, "expected 2 got %d\n", len);
6052
6053                 hr = IXMLDOMComment_get_text(pComment, &str);
6054                 ok(hr == S_OK, "ret %08x\n", hr );
6055                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6056                 SysFreeString(str);
6057
6058                 /* delete whole data ... */
6059                 hr = IXMLDOMComment_get_length(pComment, &len);
6060                 ok(hr == S_OK, "ret %08x\n", hr );
6061
6062                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6063                 ok(hr == S_OK, "ret %08x\n", hr );
6064                 /* ... and try again with empty string */
6065                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6066                 ok(hr == S_OK, "ret %08x\n", hr );
6067
6068                 /* ::replaceData() */
6069                 V_VT(&v) = VT_BSTR;
6070                 V_BSTR(&v) = SysAllocString(szstr1);
6071                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6072                 ok(hr == S_OK, "ret %08x\n", hr );
6073                 VariantClear(&v);
6074
6075                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6076                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6077                 hr = IXMLDOMComment_get_text(pComment, &str);
6078                 ok(hr == S_OK, "ret %08x\n", hr );
6079                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6080                 SysFreeString(str);
6081
6082                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6083                 ok(hr == S_OK, "ret %08x\n", hr );
6084                 hr = IXMLDOMComment_get_text(pComment, &str);
6085                 ok(hr == S_OK, "ret %08x\n", hr );
6086                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6087                 SysFreeString(str);
6088
6089                 /* NULL pointer means delete */
6090                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6091                 ok(hr == S_OK, "ret %08x\n", hr );
6092                 hr = IXMLDOMComment_get_text(pComment, &str);
6093                 ok(hr == S_OK, "ret %08x\n", hr );
6094                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6095                 SysFreeString(str);
6096
6097                 /* empty string means delete */
6098                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6099                 ok(hr == S_OK, "ret %08x\n", hr );
6100                 hr = IXMLDOMComment_get_text(pComment, &str);
6101                 ok(hr == S_OK, "ret %08x\n", hr );
6102                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6103                 SysFreeString(str);
6104
6105                 /* zero count means insert */
6106                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6107                 ok(hr == S_OK, "ret %08x\n", hr );
6108                 hr = IXMLDOMComment_get_text(pComment, &str);
6109                 ok(hr == S_OK, "ret %08x\n", hr );
6110                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6111                 SysFreeString(str);
6112
6113                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6114                 ok(hr == S_OK, "ret %08x\n", hr );
6115
6116                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6117                 ok(hr == S_OK, "ret %08x\n", hr );
6118                 hr = IXMLDOMComment_get_text(pComment, &str);
6119                 ok(hr == S_OK, "ret %08x\n", hr );
6120                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6121                 SysFreeString(str);
6122
6123                 /* nonempty string, count greater than its length */
6124                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6125                 ok(hr == S_OK, "ret %08x\n", hr );
6126                 hr = IXMLDOMComment_get_text(pComment, &str);
6127                 ok(hr == S_OK, "ret %08x\n", hr );
6128                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6129                 SysFreeString(str);
6130
6131                 /* nonempty string, count less than its length */
6132                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6133                 ok(hr == S_OK, "ret %08x\n", hr );
6134                 hr = IXMLDOMComment_get_text(pComment, &str);
6135                 ok(hr == S_OK, "ret %08x\n", hr );
6136                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6137                 SysFreeString(str);
6138
6139                 IXMLDOMComment_Release(pComment);
6140             }
6141
6142             /* Element */
6143             str = SysAllocString(szElement);
6144             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6145             SysFreeString(str);
6146             ok(hr == S_OK, "ret %08x\n", hr );
6147             if(hr == S_OK)
6148             {
6149                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6150                 ok(hr == S_OK, "ret %08x\n", hr );
6151
6152                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6153                 ok(hr == S_OK, "ret %08x\n", hr );
6154                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6155                 SysFreeString(str);
6156
6157                 hr = IXMLDOMElement_get_xml(pElement, &str);
6158                 ok(hr == S_OK, "ret %08x\n", hr );
6159                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6160                 SysFreeString(str);
6161
6162                 /* Attribute */
6163                 pAttribute = (IXMLDOMAttribute*)0x1;
6164                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6165                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6166                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6167
6168                 pAttribute = (IXMLDOMAttribute*)0x1;
6169                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6170                 ok(hr == E_FAIL, "ret %08x\n", hr );
6171                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6172
6173                 str = SysAllocString(szAttribute);
6174                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6175                 SysFreeString(str);
6176                 ok(hr == S_OK, "ret %08x\n", hr );
6177                 if(hr == S_OK)
6178                 {
6179                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6180
6181                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6182                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6183
6184                     pNextChild = (IXMLDOMNode *)0x1;
6185                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6186                     ok(hr == S_FALSE, "ret %08x\n", hr );
6187                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6188
6189                     /* test Previous Sibling*/
6190                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6191                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6192
6193                     pNextChild = (IXMLDOMNode *)0x1;
6194                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6195                     ok(hr == S_FALSE, "ret %08x\n", hr );
6196                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6197
6198                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6199                     ok(hr == E_FAIL, "ret %08x\n", hr );
6200                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6201
6202                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6203                     ok(hr == S_OK, "ret %08x\n", hr );
6204                     if ( hr == S_OK )
6205                     {
6206                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6207                         ok(hr == S_OK, "ret %08x\n", hr );
6208
6209                         IXMLDOMNamedNodeMap_Release(pAttribs);
6210                     }
6211
6212                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6213                     ok(hr == S_OK, "ret %08x\n", hr );
6214                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6215                     SysFreeString(str);
6216
6217                     /* test nodeName */
6218                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6219                     ok(hr == S_OK, "ret %08x\n", hr );
6220                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6221                     SysFreeString(str);
6222
6223                     /* test name property */
6224                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6225                     ok(hr == S_OK, "ret %08x\n", hr );
6226                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6227                     SysFreeString(str);
6228
6229                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6230                     ok(hr == S_OK, "ret %08x\n", hr );
6231                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6232                     SysFreeString(str);
6233
6234                     IXMLDOMAttribute_Release(pAttribute);
6235
6236                     /* Check Element again with the Add Attribute*/
6237                     hr = IXMLDOMElement_get_xml(pElement, &str);
6238                     ok(hr == S_OK, "ret %08x\n", hr );
6239                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6240                     SysFreeString(str);
6241                 }
6242
6243                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6244                 ok(hr == S_OK, "ret %08x\n", hr );
6245
6246                 hr = IXMLDOMElement_get_xml(pElement, &str);
6247                 ok(hr == S_OK, "ret %08x\n", hr );
6248                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6249                 SysFreeString(str);
6250
6251                 /* Test for reversible escaping */
6252                 str = SysAllocString( szStrangeChars );
6253                 hr = IXMLDOMElement_put_text(pElement, str);
6254                 ok(hr == S_OK, "ret %08x\n", hr );
6255                 SysFreeString( str );
6256
6257                 hr = IXMLDOMElement_get_xml(pElement, &str);
6258                 ok(hr == S_OK, "ret %08x\n", hr );
6259                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6260                 SysFreeString(str);
6261
6262                 hr = IXMLDOMElement_get_text(pElement, &str);
6263                 ok(hr == S_OK, "ret %08x\n", hr );
6264                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6265                 SysFreeString(str);
6266
6267                 IXMLDOMElement_Release(pElement);
6268             }
6269
6270             /* CData Section */
6271             str = SysAllocString(szCData);
6272             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6273             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6274
6275             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6276             SysFreeString(str);
6277             ok(hr == S_OK, "ret %08x\n", hr );
6278             if(hr == S_OK)
6279             {
6280                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6281                 VARIANT var;
6282
6283                 VariantInit(&var);
6284
6285                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6286                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6287
6288                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6289                 ok(hr == S_OK, "ret %08x\n", hr );
6290
6291                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6292                 ok(hr == S_OK, "ret %08x\n", hr );
6293                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6294                 SysFreeString(str);
6295
6296                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6297                 ok(hr == S_OK, "ret %08x\n", hr );
6298                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6299                 SysFreeString(str);
6300
6301                 /* test lastChild */
6302                 pNextChild = (IXMLDOMNode*)0x1;
6303                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6304                 ok(hr == S_FALSE, "ret %08x\n", hr );
6305                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6306
6307                 /* put data Tests */
6308                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6309                 ok(hr == S_OK, "ret %08x\n", hr );
6310
6311                 /* Confirm XML text is good */
6312                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6313                 ok(hr == S_OK, "ret %08x\n", hr );
6314                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6315                 SysFreeString(str);
6316
6317                 /* Confirm we get the put_data Text back */
6318                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6319                 ok(hr == S_OK, "ret %08x\n", hr );
6320                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6321                 SysFreeString(str);
6322
6323                 /* test length property */
6324                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6325                 ok(hr == S_OK, "ret %08x\n", hr );
6326                 ok(len == 21, "expected 21 got %d\n", len);
6327
6328                 /* test get data */
6329                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6330                 ok(hr == S_OK, "ret %08x\n", hr );
6331                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6332                 SysFreeString(str);
6333
6334                 /* test substringData */
6335                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6336                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6337
6338                 /* test substringData - Invalid offset */
6339                 str = (BSTR)&szElement;
6340                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6341                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6342                 ok( str == NULL, "incorrect string\n");
6343
6344                 /* test substringData - Invalid offset */
6345                 str = (BSTR)&szElement;
6346                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6347                 ok(hr == S_FALSE, "ret %08x\n", hr );
6348                 ok( str == NULL, "incorrect string\n");
6349
6350                 /* test substringData - Invalid size */
6351                 str = (BSTR)&szElement;
6352                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6353                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6354                 ok( str == NULL, "incorrect string\n");
6355
6356                 /* test substringData - Invalid size */
6357                 str = (BSTR)&szElement;
6358                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6359                 ok(hr == S_FALSE, "ret %08x\n", hr );
6360                 ok( str == NULL, "incorrect string\n");
6361
6362                 /* test substringData - Start of string */
6363                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6364                 ok(hr == S_OK, "ret %08x\n", hr );
6365                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6366                 SysFreeString(str);
6367
6368                 /* test substringData - Middle of string */
6369                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6370                 ok(hr == S_OK, "ret %08x\n", hr );
6371                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6372                 SysFreeString(str);
6373
6374                 /* test substringData - End of string */
6375                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6376                 ok(hr == S_OK, "ret %08x\n", hr );
6377                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6378                 SysFreeString(str);
6379
6380                 /* test appendData */
6381                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6382                 ok(hr == S_OK, "ret %08x\n", hr );
6383
6384                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6385                 ok(hr == S_OK, "ret %08x\n", hr );
6386
6387                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6388                 ok(hr == S_OK, "ret %08x\n", hr );
6389
6390                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6391                 ok(hr == S_OK, "ret %08x\n", hr );
6392                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6393                 SysFreeString(str);
6394
6395                 /* test insertData */
6396                 str = SysAllocStringLen(NULL, 0);
6397                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6398                 ok(hr == S_OK, "ret %08x\n", hr );
6399
6400                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6401                 ok(hr == S_OK, "ret %08x\n", hr );
6402
6403                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6404                 ok(hr == S_OK, "ret %08x\n", hr );
6405
6406                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6407                 ok(hr == S_OK, "ret %08x\n", hr );
6408
6409                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6410                 ok(hr == S_OK, "ret %08x\n", hr );
6411
6412                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6413                 ok(hr == S_OK, "ret %08x\n", hr );
6414                 SysFreeString(str);
6415
6416                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6417                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6418
6419                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6420                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6421
6422                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6423                 ok(hr == S_OK, "ret %08x\n", hr );
6424
6425                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6426                 ok(hr == S_OK, "ret %08x\n", hr );
6427
6428                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6429                 ok(hr == S_OK, "ret %08x\n", hr );
6430
6431                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6432                 ok(hr == S_OK, "ret %08x\n", hr );
6433                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6434                 SysFreeString(str);
6435
6436                 /* delete data */
6437                 /* invalid arguments */
6438                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6439                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6440
6441                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6442                 ok(hr == S_OK, "ret %08x\n", hr );
6443
6444                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6445                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6446
6447                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6448                 ok(hr == S_OK, "ret %08x\n", hr );
6449                 ok(len == 43, "expected 43 got %d\n", len);
6450
6451                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6452                 ok(hr == S_OK, "ret %08x\n", hr );
6453
6454                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6455                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6456
6457                 /* delete from start */
6458                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6459                 ok(hr == S_OK, "ret %08x\n", hr );
6460
6461                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6462                 ok(hr == S_OK, "ret %08x\n", hr );
6463                 ok(len == 38, "expected 38 got %d\n", len);
6464
6465                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6466                 ok(hr == S_OK, "ret %08x\n", hr );
6467                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6468                 SysFreeString(str);
6469
6470                 /* delete from end */
6471                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6472                 ok(hr == S_OK, "ret %08x\n", hr );
6473
6474                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6475                 ok(hr == S_OK, "ret %08x\n", hr );
6476                 ok(len == 35, "expected 35 got %d\n", len);
6477
6478                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6479                 ok(hr == S_OK, "ret %08x\n", hr );
6480                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6481                 SysFreeString(str);
6482
6483                 /* delete from inside */
6484                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6485                 ok(hr == S_OK, "ret %08x\n", hr );
6486
6487                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6488                 ok(hr == S_OK, "ret %08x\n", hr );
6489                 ok(len == 2, "expected 2 got %d\n", len);
6490
6491                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6492                 ok(hr == S_OK, "ret %08x\n", hr );
6493                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6494                 SysFreeString(str);
6495
6496                 /* delete whole data ... */
6497                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6498                 ok(hr == S_OK, "ret %08x\n", hr );
6499
6500                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6501                 ok(hr == S_OK, "ret %08x\n", hr );
6502
6503                 /* ... and try again with empty string */
6504                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6505                 ok(hr == S_OK, "ret %08x\n", hr );
6506
6507                 /* ::replaceData() */
6508                 V_VT(&v) = VT_BSTR;
6509                 V_BSTR(&v) = SysAllocString(szstr1);
6510                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6511                 ok(hr == S_OK, "ret %08x\n", hr );
6512                 VariantClear(&v);
6513
6514                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6515                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6516                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6517                 ok(hr == S_OK, "ret %08x\n", hr );
6518                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6519                 SysFreeString(str);
6520
6521                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6522                 ok(hr == S_OK, "ret %08x\n", hr );
6523                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6524                 ok(hr == S_OK, "ret %08x\n", hr );
6525                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6526                 SysFreeString(str);
6527
6528                 /* NULL pointer means delete */
6529                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6530                 ok(hr == S_OK, "ret %08x\n", hr );
6531                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6532                 ok(hr == S_OK, "ret %08x\n", hr );
6533                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6534                 SysFreeString(str);
6535
6536                 /* empty string means delete */
6537                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6538                 ok(hr == S_OK, "ret %08x\n", hr );
6539                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6540                 ok(hr == S_OK, "ret %08x\n", hr );
6541                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6542                 SysFreeString(str);
6543
6544                 /* zero count means insert */
6545                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6546                 ok(hr == S_OK, "ret %08x\n", hr );
6547                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6548                 ok(hr == S_OK, "ret %08x\n", hr );
6549                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6550                 SysFreeString(str);
6551
6552                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6553                 ok(hr == S_OK, "ret %08x\n", hr );
6554
6555                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6556                 ok(hr == S_OK, "ret %08x\n", hr );
6557                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6558                 ok(hr == S_OK, "ret %08x\n", hr );
6559                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6560                 SysFreeString(str);
6561
6562                 /* nonempty string, count greater than its length */
6563                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6564                 ok(hr == S_OK, "ret %08x\n", hr );
6565                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6566                 ok(hr == S_OK, "ret %08x\n", hr );
6567                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6568                 SysFreeString(str);
6569
6570                 /* nonempty string, count less than its length */
6571                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6572                 ok(hr == S_OK, "ret %08x\n", hr );
6573                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6574                 ok(hr == S_OK, "ret %08x\n", hr );
6575                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6576                 SysFreeString(str);
6577
6578                 IXMLDOMCDATASection_Release(pCDataSec);
6579             }
6580
6581             /* Document Fragments */
6582             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6583             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6584
6585             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6586             ok(hr == S_OK, "ret %08x\n", hr );
6587             if(hr == S_OK)
6588             {
6589                 IXMLDOMNode *node;
6590
6591                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6592                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6593
6594                 node = (IXMLDOMNode *)0x1;
6595                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6596                 ok(hr == S_FALSE, "ret %08x\n", hr );
6597                 ok(node == NULL, "expected NULL, got %p\n", node);
6598
6599                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6600                 ok(hr == S_OK, "ret %08x\n", hr );
6601
6602                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6603                 ok(hr == S_OK, "ret %08x\n", hr );
6604                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6605                 SysFreeString(str);
6606
6607                 /* test next Sibling*/
6608                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6609                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6610
6611                 node = (IXMLDOMNode *)0x1;
6612                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6613                 ok(hr == S_FALSE, "ret %08x\n", hr );
6614                 ok(node == NULL, "next sibling not NULL\n");
6615
6616                 /* test Previous Sibling*/
6617                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6618                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6619
6620                 node = (IXMLDOMNode *)0x1;
6621                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6622                 ok(hr == S_FALSE, "ret %08x\n", hr );
6623                 ok(node == NULL, "previous sibling not NULL\n");
6624
6625                 IXMLDOMDocumentFragment_Release(pDocFrag);
6626             }
6627
6628             /* Entity References */
6629             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6630             ok(hr == E_FAIL, "ret %08x\n", hr );
6631             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6632             ok(hr == E_FAIL, "ret %08x\n", hr );
6633
6634             str = SysAllocString(szEntityRef);
6635             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6636             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6637
6638             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6639             SysFreeString(str);
6640             ok(hr == S_OK, "ret %08x\n", hr );
6641             if(hr == S_OK)
6642             {
6643                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6644                 ok(hr == S_OK, "ret %08x\n", hr );
6645
6646                 /* test get_xml*/
6647                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6648                 ok(hr == S_OK, "ret %08x\n", hr );
6649                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6650                 SysFreeString(str);
6651
6652                 IXMLDOMEntityReference_Release(pEntityRef);
6653             }
6654
6655             IXMLDOMElement_Release( pRoot );
6656         }
6657     }
6658
6659     IXMLDOMDocument_Release(doc);
6660
6661     free_bstrs();
6662 }
6663
6664 static void test_nodeTypeTests( void )
6665 {
6666     IXMLDOMDocument *doc = NULL;
6667     IXMLDOMElement *pRoot;
6668     IXMLDOMElement *pElement;
6669     HRESULT hr;
6670
6671     doc = create_document(&IID_IXMLDOMDocument);
6672     if (!doc) return;
6673
6674     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6675     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6676
6677     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6678     ok(hr == S_OK, "ret %08x\n", hr );
6679     if(hr == S_OK)
6680     {
6681         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6682         ok(hr == S_OK, "ret %08x\n", hr );
6683         if(hr == S_OK)
6684         {
6685             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
6686             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6687
6688             /* Invalid Value */
6689             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
6690             ok(hr == E_FAIL, "ret %08x\n", hr );
6691
6692             /* NOTE:
6693              *   The name passed into put_dataType is case-insensitive. So many of the names
6694              *     have been changed to reflect this.
6695              */
6696             /* Boolean */
6697             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
6698             ok(hr == S_OK, "ret %08x\n", hr );
6699             if(hr == S_OK)
6700             {
6701                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6702
6703                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
6704                 ok(hr == S_OK, "ret %08x\n", hr );
6705
6706                 IXMLDOMElement_Release(pElement);
6707             }
6708
6709             /* String */
6710             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
6711             ok(hr == S_OK, "ret %08x\n", hr );
6712             if(hr == S_OK)
6713             {
6714                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6715
6716                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
6717                 ok(hr == S_OK, "ret %08x\n", hr );
6718
6719                 IXMLDOMElement_Release(pElement);
6720             }
6721
6722             /* Number */
6723             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
6724             ok(hr == S_OK, "ret %08x\n", hr );
6725             if(hr == S_OK)
6726             {
6727                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6728
6729                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
6730                 ok(hr == S_OK, "ret %08x\n", hr );
6731
6732                 IXMLDOMElement_Release(pElement);
6733             }
6734
6735             /* Int */
6736             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
6737             ok(hr == S_OK, "ret %08x\n", hr );
6738             if(hr == S_OK)
6739             {
6740                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6741
6742                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
6743                 ok(hr == S_OK, "ret %08x\n", hr );
6744
6745                 IXMLDOMElement_Release(pElement);
6746             }
6747
6748             /* Fixed */
6749             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
6750             ok(hr == S_OK, "ret %08x\n", hr );
6751             if(hr == S_OK)
6752             {
6753                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6754
6755                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
6756                 ok(hr == S_OK, "ret %08x\n", hr );
6757
6758                 IXMLDOMElement_Release(pElement);
6759             }
6760
6761             /* DateTime */
6762             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
6763             ok(hr == S_OK, "ret %08x\n", hr );
6764             if(hr == S_OK)
6765             {
6766                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6767
6768                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
6769                 ok(hr == S_OK, "ret %08x\n", hr );
6770
6771                 IXMLDOMElement_Release(pElement);
6772             }
6773
6774             /* DateTime TZ */
6775             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
6776             ok(hr == S_OK, "ret %08x\n", hr );
6777             if(hr == S_OK)
6778             {
6779                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6780
6781                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6782                 ok(hr == S_OK, "ret %08x\n", hr );
6783
6784                 IXMLDOMElement_Release(pElement);
6785             }
6786
6787             /* Date */
6788             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
6789             ok(hr == S_OK, "ret %08x\n", hr );
6790             if(hr == S_OK)
6791             {
6792                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6793
6794                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
6795                 ok(hr == S_OK, "ret %08x\n", hr );
6796
6797                 IXMLDOMElement_Release(pElement);
6798             }
6799
6800             /* Time */
6801             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
6802             ok(hr == S_OK, "ret %08x\n", hr );
6803             if(hr == S_OK)
6804             {
6805                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6806
6807                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
6808                 ok(hr == S_OK, "ret %08x\n", hr );
6809
6810                 IXMLDOMElement_Release(pElement);
6811             }
6812
6813             /* Time.tz */
6814             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
6815             ok(hr == S_OK, "ret %08x\n", hr );
6816             if(hr == S_OK)
6817             {
6818                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6819
6820                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
6821                 ok(hr == S_OK, "ret %08x\n", hr );
6822
6823                 IXMLDOMElement_Release(pElement);
6824             }
6825
6826             /* I1 */
6827             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
6828             ok(hr == S_OK, "ret %08x\n", hr );
6829             if(hr == S_OK)
6830             {
6831                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6832
6833                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
6834                 ok(hr == S_OK, "ret %08x\n", hr );
6835
6836                 IXMLDOMElement_Release(pElement);
6837             }
6838
6839             /* I2 */
6840             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
6841             ok(hr == S_OK, "ret %08x\n", hr );
6842             if(hr == S_OK)
6843             {
6844                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6845
6846                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
6847                 ok(hr == S_OK, "ret %08x\n", hr );
6848
6849                 IXMLDOMElement_Release(pElement);
6850             }
6851
6852             /* I4 */
6853             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
6854             ok(hr == S_OK, "ret %08x\n", hr );
6855             if(hr == S_OK)
6856             {
6857                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6858
6859                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
6860                 ok(hr == S_OK, "ret %08x\n", hr );
6861
6862                 IXMLDOMElement_Release(pElement);
6863             }
6864
6865             /* UI1 */
6866             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
6867             ok(hr == S_OK, "ret %08x\n", hr );
6868             if(hr == S_OK)
6869             {
6870                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6871
6872                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
6873                 ok(hr == S_OK, "ret %08x\n", hr );
6874
6875                 IXMLDOMElement_Release(pElement);
6876             }
6877
6878             /* UI2 */
6879             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
6880             ok(hr == S_OK, "ret %08x\n", hr );
6881             if(hr == S_OK)
6882             {
6883                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6884
6885                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
6886                 ok(hr == S_OK, "ret %08x\n", hr );
6887
6888                 IXMLDOMElement_Release(pElement);
6889             }
6890
6891             /* UI4 */
6892             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
6893             ok(hr == S_OK, "ret %08x\n", hr );
6894             if(hr == S_OK)
6895             {
6896                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6897
6898                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
6899                 ok(hr == S_OK, "ret %08x\n", hr );
6900
6901                 IXMLDOMElement_Release(pElement);
6902             }
6903
6904             /* r4 */
6905             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
6906             ok(hr == S_OK, "ret %08x\n", hr );
6907             if(hr == S_OK)
6908             {
6909                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6910
6911                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
6912                 ok(hr == S_OK, "ret %08x\n", hr );
6913
6914                 IXMLDOMElement_Release(pElement);
6915             }
6916
6917             /* r8 */
6918             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
6919             ok(hr == S_OK, "ret %08x\n", hr );
6920             if(hr == S_OK)
6921             {
6922                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6923
6924                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
6925                 ok(hr == S_OK, "ret %08x\n", hr );
6926
6927                 IXMLDOMElement_Release(pElement);
6928             }
6929
6930             /* float */
6931             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
6932             ok(hr == S_OK, "ret %08x\n", hr );
6933             if(hr == S_OK)
6934             {
6935                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6936
6937                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
6938                 ok(hr == S_OK, "ret %08x\n", hr );
6939
6940                 IXMLDOMElement_Release(pElement);
6941             }
6942
6943             /* uuid */
6944             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
6945             ok(hr == S_OK, "ret %08x\n", hr );
6946             if(hr == S_OK)
6947             {
6948                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6949
6950                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
6951                 ok(hr == S_OK, "ret %08x\n", hr );
6952
6953                 IXMLDOMElement_Release(pElement);
6954             }
6955
6956             /* bin.hex */
6957             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
6958             ok(hr == S_OK, "ret %08x\n", hr );
6959             if(hr == S_OK)
6960             {
6961                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6962
6963                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
6964                 ok(hr == S_OK, "ret %08x\n", hr );
6965
6966                 IXMLDOMElement_Release(pElement);
6967             }
6968
6969             /* bin.base64 */
6970             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
6971             ok(hr == S_OK, "ret %08x\n", hr );
6972             if(hr == S_OK)
6973             {
6974                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6975
6976                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
6977                 ok(hr == S_OK, "ret %08x\n", hr );
6978
6979                 IXMLDOMElement_Release(pElement);
6980             }
6981
6982             /* Check changing types */
6983             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
6984             ok(hr == S_OK, "ret %08x\n", hr );
6985             if(hr == S_OK)
6986             {
6987                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6988
6989                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
6990                 ok(hr == S_OK, "ret %08x\n", hr );
6991
6992                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
6993                 ok(hr == S_OK, "ret %08x\n", hr );
6994
6995                 IXMLDOMElement_Release(pElement);
6996             }
6997
6998             IXMLDOMElement_Release(pRoot);
6999         }
7000     }
7001
7002     IXMLDOMDocument_Release(doc);
7003
7004     free_bstrs();
7005 }
7006
7007 static void test_save(void)
7008 {
7009     IXMLDOMDocument *doc, *doc2;
7010     IXMLDOMElement *root;
7011     VARIANT file, vDoc;
7012     BSTR sOrig, sNew, filename;
7013     char buffer[100];
7014     DWORD read = 0;
7015     HANDLE hfile;
7016     HRESULT hr;
7017
7018     doc = create_document(&IID_IXMLDOMDocument);
7019     if (!doc) return;
7020
7021     doc2 = create_document(&IID_IXMLDOMDocument);
7022     if (!doc2)
7023     {
7024         IXMLDOMDocument_Release(doc);
7025         return;
7026     }
7027
7028     /* save to IXMLDOMDocument */
7029     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7030     EXPECT_HR(hr, S_OK);
7031
7032     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7033     EXPECT_HR(hr, S_OK);
7034
7035     V_VT(&vDoc) = VT_UNKNOWN;
7036     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
7037
7038     hr = IXMLDOMDocument_save(doc, vDoc);
7039     EXPECT_HR(hr, S_OK);
7040
7041     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7042     EXPECT_HR(hr, S_OK);
7043
7044     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7045     EXPECT_HR(hr, S_OK);
7046
7047     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7048
7049     SysFreeString(sOrig);
7050     SysFreeString(sNew);
7051
7052     IXMLDOMElement_Release(root);
7053     IXMLDOMDocument_Release(doc2);
7054
7055     /* save to path */
7056     V_VT(&file) = VT_BSTR;
7057     V_BSTR(&file) = _bstr_("test.xml");
7058
7059     hr = IXMLDOMDocument_save(doc, file);
7060     EXPECT_HR(hr, S_OK);
7061
7062     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7063     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7064     if(hfile == INVALID_HANDLE_VALUE) return;
7065
7066     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7067     ok(read != 0, "could not read file\n");
7068     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7069
7070     CloseHandle(hfile);
7071     DeleteFile("test.xml");
7072
7073     /* save to path VT_BSTR | VT_BYREF */
7074     filename = _bstr_("test.xml");
7075     V_VT(&file) = VT_BSTR | VT_BYREF;
7076     V_BSTRREF(&file) = &filename;
7077
7078     hr = IXMLDOMDocument_save(doc, file);
7079     EXPECT_HR(hr, S_OK);
7080
7081     IXMLDOMDocument_Release(doc);
7082
7083     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7084     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7085     if(hfile == INVALID_HANDLE_VALUE) return;
7086
7087     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7088     ok(read != 0, "could not read file\n");
7089     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7090
7091     CloseHandle(hfile);
7092     DeleteFile("test.xml");
7093     free_bstrs();
7094 }
7095
7096 static void test_testTransforms(void)
7097 {
7098     IXMLDOMDocument *doc, *docSS;
7099     IXMLDOMNode *pNode;
7100     VARIANT_BOOL bSucc;
7101
7102     HRESULT hr;
7103
7104     doc = create_document(&IID_IXMLDOMDocument);
7105     if (!doc) return;
7106
7107     docSS = create_document(&IID_IXMLDOMDocument);
7108     if (!docSS)
7109     {
7110         IXMLDOMDocument_Release(doc);
7111         return;
7112     }
7113
7114     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7115     ok(hr == S_OK, "ret %08x\n", hr );
7116
7117     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7118     ok(hr == S_OK, "ret %08x\n", hr );
7119
7120     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7121     ok(hr == S_OK, "ret %08x\n", hr );
7122     if(hr == S_OK)
7123     {
7124         BSTR bOut;
7125
7126         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7127         ok(hr == S_OK, "ret %08x\n", hr );
7128         if(hr == S_OK)
7129         {
7130             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7131             SysFreeString(bOut);
7132         }
7133
7134         IXMLDOMNode_Release(pNode);
7135     }
7136
7137     IXMLDOMDocument_Release(docSS);
7138     IXMLDOMDocument_Release(doc);
7139
7140     free_bstrs();
7141 }
7142
7143 static void test_namespaces(void)
7144 {
7145     static const CHAR namespaces_xmlA[] =
7146         "<?xml version=\"1.0\"?>\n"
7147         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7148         "  <XMI.content>"
7149         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7150         "  </XMI.content>"
7151         "</XMI>";
7152
7153     IXMLDOMDocument *doc;
7154     IXMLDOMElement *elem;
7155     IXMLDOMNode *node;
7156
7157     VARIANT_BOOL b;
7158     VARIANT var;
7159     HRESULT hr;
7160     BSTR str;
7161
7162     doc = create_document(&IID_IXMLDOMDocument);
7163     if (!doc) return;
7164
7165     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7166     EXPECT_HR(hr, S_OK);
7167     ok(b == VARIANT_TRUE, "got %d\n", b);
7168
7169     str = (BSTR)0xdeadbeef;
7170     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7171     EXPECT_HR(hr, S_FALSE);
7172     ok(str == NULL, "got %p\n", str);
7173
7174     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7175     EXPECT_HR(hr, S_OK);
7176     if(hr == S_OK)
7177     {
7178         IXMLDOMAttribute *attr;
7179         IXMLDOMNode *node2;
7180
7181         hr = IXMLDOMNode_get_firstChild(node, &node2);
7182         EXPECT_HR(hr, S_OK);
7183         ok(node2 != NULL, "got %p\n", node2);
7184
7185         /* Test get_prefix */
7186         hr = IXMLDOMNode_get_prefix(node2, NULL);
7187         EXPECT_HR(hr, E_INVALIDARG);
7188         /* NOTE: Need to test that arg2 gets cleared on Error. */
7189
7190         hr = IXMLDOMNode_get_prefix(node2, &str);
7191         EXPECT_HR(hr, S_OK);
7192         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7193         SysFreeString(str);
7194
7195         hr = IXMLDOMNode_get_nodeName(node2, &str);
7196         EXPECT_HR(hr, S_OK);
7197         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7198         SysFreeString(str);
7199
7200         /* Test get_namespaceURI */
7201         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7202         EXPECT_HR(hr, E_INVALIDARG);
7203         /* NOTE: Need to test that arg2 gets cleared on Error. */
7204
7205         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7206         EXPECT_HR(hr, S_OK);
7207         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7208         SysFreeString(str);
7209
7210         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7211         EXPECT_HR(hr, S_OK);
7212
7213         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7214         EXPECT_HR(hr, S_OK);
7215
7216         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7217         EXPECT_HR(hr, S_OK);
7218         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7219         SysFreeString(str);
7220
7221         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7222         EXPECT_HR(hr, S_OK);
7223         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7224         SysFreeString(str);
7225
7226         IXMLDOMAttribute_Release(attr);
7227         IXMLDOMElement_Release(elem);
7228
7229         IXMLDOMNode_Release(node2);
7230         IXMLDOMNode_Release(node);
7231     }
7232
7233     IXMLDOMDocument_Release(doc);
7234
7235     /* create on element and try to alter namespace after that */
7236     doc = create_document(&IID_IXMLDOMDocument);
7237     if (!doc) return;
7238
7239     V_VT(&var) = VT_I2;
7240     V_I2(&var) = NODE_ELEMENT;
7241
7242     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7243     EXPECT_HR(hr, S_OK);
7244
7245     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7246     EXPECT_HR(hr, S_OK);
7247
7248     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7249     EXPECT_HR(hr, S_OK);
7250
7251     V_VT(&var) = VT_BSTR;
7252     V_BSTR(&var) = _bstr_("ns/uri2");
7253
7254     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7255     EXPECT_HR(hr, E_INVALIDARG);
7256
7257     V_VT(&var) = VT_BSTR;
7258     V_BSTR(&var) = _bstr_("ns/uri");
7259
7260     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7261     EXPECT_HR(hr, S_OK);
7262
7263     hr = IXMLDOMElement_get_xml(elem, &str);
7264     EXPECT_HR(hr, S_OK);
7265     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7266     SysFreeString(str);
7267
7268     IXMLDOMElement_Release(elem);
7269     IXMLDOMDocument_Release(doc);
7270
7271     /* create on element and try to alter namespace after that */
7272     doc = create_document_version(60, &IID_IXMLDOMDocument);
7273     if (!doc) return;
7274
7275     V_VT(&var) = VT_I2;
7276     V_I2(&var) = NODE_ELEMENT;
7277
7278     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7279     EXPECT_HR(hr, S_OK);
7280
7281     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7282     EXPECT_HR(hr, S_OK);
7283
7284     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7285     EXPECT_HR(hr, S_OK);
7286
7287     /* try same prefix, different uri */
7288     V_VT(&var) = VT_BSTR;
7289     V_BSTR(&var) = _bstr_("ns/uri2");
7290
7291     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7292     EXPECT_HR(hr, E_INVALIDARG);
7293
7294     /* try same prefix and uri */
7295     V_VT(&var) = VT_BSTR;
7296     V_BSTR(&var) = _bstr_("ns/uri");
7297
7298     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7299     EXPECT_HR(hr, S_OK);
7300
7301     hr = IXMLDOMElement_get_xml(elem, &str);
7302     EXPECT_HR(hr, S_OK);
7303     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7304     SysFreeString(str);
7305
7306     IXMLDOMElement_Release(elem);
7307     IXMLDOMDocument_Release(doc);
7308
7309     free_bstrs();
7310 }
7311
7312 static void test_FormattingXML(void)
7313 {
7314     IXMLDOMDocument *doc;
7315     IXMLDOMElement *pElement;
7316     VARIANT_BOOL bSucc;
7317     HRESULT hr;
7318     BSTR str;
7319     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7320     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7321
7322     doc = create_document(&IID_IXMLDOMDocument);
7323     if (!doc) return;
7324
7325     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7326     ok(hr == S_OK, "ret %08x\n", hr );
7327     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7328
7329     if(bSucc == VARIANT_TRUE)
7330     {
7331         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7332         ok(hr == S_OK, "ret %08x\n", hr );
7333         if(hr == S_OK)
7334         {
7335             hr = IXMLDOMElement_get_xml(pElement, &str);
7336             ok(hr == S_OK, "ret %08x\n", hr );
7337             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7338             SysFreeString(str);
7339
7340             IXMLDOMElement_Release(pElement);
7341         }
7342     }
7343
7344     IXMLDOMDocument_Release(doc);
7345
7346     free_bstrs();
7347 }
7348
7349 typedef struct _nodetypedvalue_t {
7350     const char *name;
7351     VARTYPE type;
7352     const char *value; /* value in string format */
7353 } nodetypedvalue_t;
7354
7355 static const nodetypedvalue_t get_nodetypedvalue[] = {
7356     { "root/string",    VT_BSTR, "Wine" },
7357     { "root/string2",   VT_BSTR, "String" },
7358     { "root/number",    VT_BSTR, "12.44" },
7359     { "root/number2",   VT_BSTR, "-3.71e3" },
7360     { "root/int",       VT_I4,   "-13" },
7361     { "root/fixed",     VT_CY,   "7322.9371" },
7362     { "root/bool",      VT_BOOL, "-1" },
7363     { "root/datetime",  VT_DATE, "40135.14" },
7364     { "root/datetimetz",VT_DATE, "37813.59" },
7365     { "root/date",      VT_DATE, "665413" },
7366     { "root/time",      VT_DATE, "0.5813889" },
7367     { "root/timetz",    VT_DATE, "1.112512" },
7368     { "root/i1",        VT_I1,   "-13" },
7369     { "root/i2",        VT_I2,   "31915" },
7370     { "root/i4",        VT_I4,   "-312232" },
7371     { "root/ui1",       VT_UI1,  "123" },
7372     { "root/ui2",       VT_UI2,  "48282" },
7373     { "root/ui4",       VT_UI4,  "949281" },
7374     { "root/r4",        VT_R4,   "213124" },
7375     { "root/r8",        VT_R8,   "0.412" },
7376     { "root/float",     VT_R8,   "41221.421" },
7377     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7378     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7379     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7380     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7381     { 0 }
7382 };
7383
7384 static void test_nodeTypedValue(void)
7385 {
7386     const nodetypedvalue_t *entry = get_nodetypedvalue;
7387     IXMLDOMDocumentType *doctype, *doctype2;
7388     IXMLDOMProcessingInstruction *pi;
7389     IXMLDOMDocumentFragment *frag;
7390     IXMLDOMDocument *doc, *doc2;
7391     IXMLDOMCDATASection *cdata;
7392     IXMLDOMComment *comment;
7393     IXMLDOMNode *node;
7394     VARIANT_BOOL b;
7395     VARIANT value;
7396     HRESULT hr;
7397
7398     doc = create_document(&IID_IXMLDOMDocument);
7399     if (!doc) return;
7400
7401     b = VARIANT_FALSE;
7402     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7403     ok(hr == S_OK, "ret %08x\n", hr );
7404     ok(b == VARIANT_TRUE, "got %d\n", b);
7405
7406     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7407     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7408
7409     V_VT(&value) = VT_BSTR;
7410     V_BSTR(&value) = NULL;
7411     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7412     ok(hr == S_FALSE, "ret %08x\n", hr );
7413     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7414
7415     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7416     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7417
7418     V_VT(&value) = VT_EMPTY;
7419     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7420     ok(hr == S_FALSE, "ret %08x\n", hr );
7421     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7422
7423     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7424     ok(hr == S_OK, "ret %08x\n", hr );
7425
7426     V_VT(&value) = VT_BSTR;
7427     V_BSTR(&value) = NULL;
7428     hr = IXMLDOMNode_get_nodeValue(node, &value);
7429     ok(hr == S_FALSE, "ret %08x\n", hr );
7430     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7431
7432     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7433     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7434
7435     IXMLDOMNode_Release(node);
7436
7437     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7438     ok(hr == S_OK, "ret %08x\n", hr );
7439     {
7440         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7441
7442         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7443         ok(hr == S_OK, "ret %08x\n", hr );
7444         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7445         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7446         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7447             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7448         VariantClear(&value);
7449         IXMLDOMNode_Release(node);
7450     }
7451
7452     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7453     ok(hr == S_OK, "ret %08x\n", hr );
7454     {
7455         V_VT(&value) = VT_NULL;
7456         V_BSTR(&value) = (void*)0xdeadbeef;
7457         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7458         ok(hr == S_OK, "ret %08x\n", hr );
7459         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7460         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7461         IXMLDOMProcessingInstruction_Release(pi);
7462         VariantClear(&value);
7463     }
7464
7465     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7466     ok(hr == S_OK, "ret %08x\n", hr );
7467     {
7468         V_VT(&value) = VT_NULL;
7469         V_BSTR(&value) = (void*)0xdeadbeef;
7470         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7471         ok(hr == S_OK, "ret %08x\n", hr );
7472         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7473         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7474         IXMLDOMCDATASection_Release(cdata);
7475         VariantClear(&value);
7476     }
7477
7478     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7479     ok(hr == S_OK, "ret %08x\n", hr );
7480     {
7481         V_VT(&value) = VT_NULL;
7482         V_BSTR(&value) = (void*)0xdeadbeef;
7483         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7484         ok(hr == S_OK, "ret %08x\n", hr );
7485         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7486         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7487         IXMLDOMComment_Release(comment);
7488         VariantClear(&value);
7489     }
7490
7491     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7492     ok(hr == S_OK, "ret %08x\n", hr );
7493     {
7494         V_VT(&value) = VT_EMPTY;
7495         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7496         ok(hr == S_FALSE, "ret %08x\n", hr );
7497         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7498         IXMLDOMDocumentFragment_Release(frag);
7499     }
7500
7501     doc2 = create_document(&IID_IXMLDOMDocument);
7502
7503     b = VARIANT_FALSE;
7504     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7505     ok(hr == S_OK, "ret %08x\n", hr );
7506     ok(b == VARIANT_TRUE, "got %d\n", b);
7507
7508     EXPECT_REF(doc2, 1);
7509
7510     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7511     ok(hr == S_OK, "ret %08x\n", hr );
7512
7513     EXPECT_REF(doc2, 1);
7514     todo_wine EXPECT_REF(doctype, 2);
7515
7516     {
7517         V_VT(&value) = VT_EMPTY;
7518         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7519         ok(hr == S_FALSE, "ret %08x\n", hr );
7520         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7521     }
7522
7523     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7524     ok(hr == S_OK, "ret %08x\n", hr );
7525     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7526
7527     IXMLDOMDocumentType_Release(doctype2);
7528     IXMLDOMDocumentType_Release(doctype);
7529
7530     IXMLDOMDocument_Release(doc2);
7531
7532     while (entry->name)
7533     {
7534         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7535         ok(hr == S_OK, "ret %08x\n", hr );
7536
7537         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7538         ok(hr == S_OK, "ret %08x\n", hr );
7539         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7540
7541         if (entry->type == (VT_ARRAY|VT_UI1))
7542         {
7543             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7544                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7545         }
7546
7547         if (entry->type != VT_BSTR)
7548         {
7549            if (entry->type == VT_DATE ||
7550                entry->type == VT_R8 ||
7551                entry->type == VT_CY)
7552            {
7553                if (entry->type == VT_DATE)
7554                {
7555                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7556                    ok(hr == S_OK, "ret %08x\n", hr );
7557                }
7558                hr = VariantChangeTypeEx(&value, &value,
7559                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7560                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7561                ok(hr == S_OK, "ret %08x\n", hr );
7562            }
7563            else
7564            {
7565                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7566                ok(hr == S_OK, "ret %08x\n", hr );
7567            }
7568
7569            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7570            if (entry->type == (VT_ARRAY|VT_UI1))
7571            {
7572                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7573                   "expected %s\n", entry->value);
7574            }
7575            else
7576                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7577                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7578         }
7579         else
7580            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7581                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7582
7583         VariantClear( &value );
7584         IXMLDOMNode_Release(node);
7585
7586         entry++;
7587     }
7588
7589     IXMLDOMDocument_Release(doc);
7590     free_bstrs();
7591 }
7592
7593 static void test_TransformWithLoadingLocalFile(void)
7594 {
7595     IXMLDOMDocument *doc;
7596     IXMLDOMDocument *xsl;
7597     IXMLDOMNode *pNode;
7598     VARIANT_BOOL bSucc;
7599     HRESULT hr;
7600     HANDLE file;
7601     DWORD dwWritten;
7602     char lpPathBuffer[MAX_PATH];
7603     int i;
7604
7605     /* Create a Temp File. */
7606     GetTempPathA(MAX_PATH, lpPathBuffer);
7607     strcat(lpPathBuffer, "customers.xml" );
7608
7609     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7610     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7611     if(file == INVALID_HANDLE_VALUE)
7612         return;
7613
7614     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7615     CloseHandle(file);
7616
7617     /* Correct path to not include a escape character. */
7618     for(i=0; i < strlen(lpPathBuffer); i++)
7619     {
7620         if(lpPathBuffer[i] == '\\')
7621             lpPathBuffer[i] = '/';
7622     }
7623
7624     doc = create_document(&IID_IXMLDOMDocument);
7625     if (!doc) return;
7626
7627     xsl = create_document(&IID_IXMLDOMDocument);
7628     if (!xsl)
7629     {
7630         IXMLDOMDocument2_Release(doc);
7631         return;
7632     }
7633
7634     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7635     ok(hr == S_OK, "ret %08x\n", hr );
7636     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7637     if(bSucc == VARIANT_TRUE)
7638     {
7639         BSTR sXSL;
7640         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7641         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7642         BSTR sFileName = _bstr_(lpPathBuffer);
7643         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7644
7645         sXSL = SysAllocStringLen(NULL, nLegnth);
7646         lstrcpyW(sXSL, sPart1);
7647         lstrcatW(sXSL, sFileName);
7648         lstrcatW(sXSL, sPart2);
7649
7650         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7651         ok(hr == S_OK, "ret %08x\n", hr );
7652         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7653         if(bSucc == VARIANT_TRUE)
7654         {
7655             BSTR sResult;
7656
7657             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7658             ok(hr == S_OK, "ret %08x\n", hr );
7659             if(hr == S_OK)
7660             {
7661                 /* This will load the temp file via the XSL */
7662                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7663                 ok(hr == S_OK, "ret %08x\n", hr );
7664                 if(hr == S_OK)
7665                 {
7666                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7667                     SysFreeString(sResult);
7668                 }
7669
7670                 IXMLDOMNode_Release(pNode);
7671             }
7672         }
7673
7674         SysFreeString(sXSL);
7675     }
7676
7677     IXMLDOMDocument_Release(doc);
7678     IXMLDOMDocument_Release(xsl);
7679
7680     DeleteFile(lpPathBuffer);
7681     free_bstrs();
7682 }
7683
7684 static void test_put_nodeValue(void)
7685 {
7686     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7687     IXMLDOMDocument *doc;
7688     IXMLDOMText *text;
7689     IXMLDOMEntityReference *entityref;
7690     IXMLDOMAttribute *attr;
7691     IXMLDOMNode *node;
7692     HRESULT hr;
7693     VARIANT data, type;
7694
7695     doc = create_document(&IID_IXMLDOMDocument);
7696     if (!doc) return;
7697
7698     /* test for unsupported types */
7699     /* NODE_DOCUMENT */
7700     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7701     ok(hr == S_OK, "ret %08x\n", hr );
7702     V_VT(&data) = VT_BSTR;
7703     V_BSTR(&data) = _bstr_("one two three");
7704     hr = IXMLDOMNode_put_nodeValue(node, data);
7705     ok(hr == E_FAIL, "ret %08x\n", hr );
7706     IXMLDOMNode_Release(node);
7707
7708     /* NODE_DOCUMENT_FRAGMENT */
7709     V_VT(&type) = VT_I1;
7710     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7711     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7712     ok(hr == S_OK, "ret %08x\n", hr );
7713     V_VT(&data) = VT_BSTR;
7714     V_BSTR(&data) = _bstr_("one two three");
7715     hr = IXMLDOMNode_put_nodeValue(node, data);
7716     ok(hr == E_FAIL, "ret %08x\n", hr );
7717     IXMLDOMNode_Release(node);
7718
7719     /* NODE_ELEMENT */
7720     V_VT(&type) = VT_I1;
7721     V_I1(&type) = NODE_ELEMENT;
7722     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7723     ok(hr == S_OK, "ret %08x\n", hr );
7724     V_VT(&data) = VT_BSTR;
7725     V_BSTR(&data) = _bstr_("one two three");
7726     hr = IXMLDOMNode_put_nodeValue(node, data);
7727     ok(hr == E_FAIL, "ret %08x\n", hr );
7728     IXMLDOMNode_Release(node);
7729
7730     /* NODE_ENTITY_REFERENCE */
7731     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7732     ok(hr == S_OK, "ret %08x\n", hr );
7733
7734     V_VT(&data) = VT_BSTR;
7735     V_BSTR(&data) = _bstr_("one two three");
7736     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7737     ok(hr == E_FAIL, "ret %08x\n", hr );
7738
7739     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7740     ok(hr == S_OK, "ret %08x\n", hr );
7741     V_VT(&data) = VT_BSTR;
7742     V_BSTR(&data) = _bstr_("one two three");
7743     hr = IXMLDOMNode_put_nodeValue(node, data);
7744     ok(hr == E_FAIL, "ret %08x\n", hr );
7745     IXMLDOMNode_Release(node);
7746     IXMLDOMEntityReference_Release(entityref);
7747
7748     /* supported types */
7749     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7750     ok(hr == S_OK, "ret %08x\n", hr );
7751     V_VT(&data) = VT_BSTR;
7752     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7753     hr = IXMLDOMText_put_nodeValue(text, data);
7754     ok(hr == S_OK, "ret %08x\n", hr );
7755     IXMLDOMText_Release(text);
7756
7757     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7758     ok(hr == S_OK, "ret %08x\n", hr );
7759     V_VT(&data) = VT_BSTR;
7760     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7761     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7762     ok(hr == S_OK, "ret %08x\n", hr );
7763     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7764     ok(hr == S_OK, "ret %08x\n", hr );
7765     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7766         wine_dbgstr_w(V_BSTR(&data)));
7767     VariantClear(&data);
7768     IXMLDOMAttribute_Release(attr);
7769
7770     free_bstrs();
7771
7772     IXMLDOMDocument_Release(doc);
7773 }
7774
7775 static void test_document_IObjectSafety(void)
7776 {
7777     IXMLDOMDocument *doc;
7778     IObjectSafety *safety;
7779     HRESULT hr;
7780
7781     doc = create_document(&IID_IXMLDOMDocument);
7782     if (!doc) return;
7783
7784     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7785     ok(hr == S_OK, "ret %08x\n", hr );
7786
7787     test_IObjectSafety_common(safety);
7788
7789     IObjectSafety_Release(safety);
7790
7791     IXMLDOMDocument_Release(doc);
7792 }
7793
7794 typedef struct _property_test_t {
7795     const GUID *guid;
7796     const char *clsid;
7797     const char *property;
7798     const char *value;
7799 } property_test_t;
7800
7801 static const property_test_t properties_test_data[] = {
7802     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7803     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7804     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7805     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7806     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7807     { 0 }
7808 };
7809
7810 static void test_default_properties(void)
7811 {
7812     const property_test_t *entry = properties_test_data;
7813
7814     while (entry->guid)
7815     {
7816         IXMLDOMDocument2 *doc;
7817         VARIANT var;
7818         HRESULT hr;
7819
7820         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7821         if (hr != S_OK)
7822         {
7823             win_skip("can't create %s instance\n", entry->clsid);
7824             entry++;
7825             continue;
7826         }
7827
7828         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7829         ok(hr == S_OK, "got 0x%08x\n", hr);
7830         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7831            entry->value, entry->clsid);
7832         VariantClear(&var);
7833
7834         IXMLDOMDocument2_Release(doc);
7835
7836         entry++;
7837     }
7838 }
7839
7840 typedef struct {
7841     const char *query;
7842     const char *list;
7843 } xslpattern_test_t;
7844
7845 static const xslpattern_test_t xslpattern_test[] = {
7846     { "root//elem[0]", "E1.E2.D1" },
7847     { "root//elem[index()=1]", "E2.E2.D1" },
7848     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7849     { "root//elem[end()]", "E4.E2.D1" },
7850     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7851     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7852     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7853     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7854     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7855     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7856     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7857     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7858     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7859     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7860     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7861     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7862     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7863     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7864     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7865     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7866     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7867     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7868     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7869     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7870     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7871     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7872     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7873     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7874     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7875     { NULL }
7876 };
7877
7878 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7879     /* prefixes don't need to be registered, you may use them as they are in the doc */
7880     { "//bar:x", "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1" },
7881     /* prefixes must be explicitly specified in the name */
7882     { "//foo:elem", "" },
7883     { "//foo:c", "E3.E4.E2.D1" },
7884     { NULL }
7885 };
7886
7887 static const xslpattern_test_t xslpattern_test_func[] = {
7888     { "attribute()", "" },
7889     { "attribute('depth')", "" },
7890     { "root/attribute('depth')", "A'depth'.E3.D1" },
7891     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7892     { "//x//attribute(id)", NULL },
7893     { "//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" },
7894     { "comment()", "C2.D1" },
7895     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7896     { "element()", "E3.D1" },
7897     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7898     { "//element(a)", NULL },
7899     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7900     { "node()", "P1.D1 C2.D1 E3.D1" },
7901     { "//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" },
7902     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7903     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7904     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7905     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7906     { "pi()", "P1.D1" },
7907     { "//y/pi()", "P1.E4.E3.D1" },
7908     { "root/textnode()", "T2.E3.D1" },
7909     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7910     { NULL }
7911 };
7912
7913 static void test_XSLPattern(void)
7914 {
7915     const xslpattern_test_t *ptr = xslpattern_test;
7916     IXMLDOMDocument2 *doc;
7917     IXMLDOMNodeList *list;
7918     VARIANT_BOOL b;
7919     HRESULT hr;
7920     LONG len;
7921
7922     doc = create_document(&IID_IXMLDOMDocument2);
7923     if (!doc) return;
7924
7925     b = VARIANT_FALSE;
7926     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7927     EXPECT_HR(hr, S_OK);
7928     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7929
7930     /* switch to XSLPattern */
7931     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7932     EXPECT_HR(hr, S_OK);
7933
7934     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7935     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7936     EXPECT_HR(hr, S_OK);
7937
7938     len = 0;
7939     hr = IXMLDOMNodeList_get_length(list, &len);
7940     EXPECT_HR(hr, S_OK);
7941     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7942     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7943     IXMLDOMNodeList_Release(list);
7944
7945     while (ptr->query)
7946     {
7947         list = NULL;
7948         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7949         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7950         len = 0;
7951         hr = IXMLDOMNodeList_get_length(list, &len);
7952         ok(len != 0, "query=%s, empty list\n", ptr->query);
7953         if (len)
7954             expect_list_and_release(list, ptr->list);
7955
7956         ptr++;
7957     }
7958
7959     /* namespace handling */
7960     /* no registered namespaces */
7961     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7962     EXPECT_HR(hr, S_OK);
7963
7964     ptr = xslpattern_test_no_ns;
7965     while (ptr->query)
7966     {
7967         list = NULL;
7968         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7969         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7970
7971         if (*ptr->list)
7972         {
7973             len = 0;
7974             hr = IXMLDOMNodeList_get_length(list, &len);
7975             EXPECT_HR(hr, S_OK);
7976             ok(len != 0, "query=%s, empty list\n", ptr->query);
7977         }
7978         else
7979         {
7980             len = 1;
7981             hr = IXMLDOMNodeList_get_length(list, &len);
7982             EXPECT_HR(hr, S_OK);
7983             ok(len == 0, "query=%s, empty list\n", ptr->query);
7984         }
7985         if (len)
7986             expect_list_and_release(list, ptr->list);
7987
7988         ptr++;
7989     }
7990
7991     /* explicitly register prefix foo */
7992     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7993
7994     /* now we get the same behavior as XPath */
7995     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7996     EXPECT_HR(hr, S_OK);
7997     len = 0;
7998     hr = IXMLDOMNodeList_get_length(list, &len);
7999     EXPECT_HR(hr, S_OK);
8000     ok(len != 0, "expected filled list\n");
8001     if (len)
8002         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8003
8004     /* set prefix foo to some nonexistent namespace */
8005     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8006     EXPECT_HR(hr, S_OK);
8007
8008     /* the registered prefix takes precedence */
8009     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8010     EXPECT_HR(hr, S_OK);
8011     len = 0;
8012     hr = IXMLDOMNodeList_get_length(list, &len);
8013     EXPECT_HR(hr, S_OK);
8014     ok(len == 0, "expected empty list\n");
8015     IXMLDOMNodeList_Release(list);
8016
8017     IXMLDOMDocument2_Release(doc);
8018
8019     doc = create_document(&IID_IXMLDOMDocument2);
8020     if (!doc) return;
8021
8022     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8023     EXPECT_HR(hr, S_OK);
8024     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8025
8026     ptr = xslpattern_test_func;
8027     while (ptr->query)
8028     {
8029         list = NULL;
8030         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8031         if (ptr->list)
8032         {
8033             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8034             len = 0;
8035             hr = IXMLDOMNodeList_get_length(list, &len);
8036             if (*ptr->list)
8037             {
8038                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8039                 if (len)
8040                     expect_list_and_release(list, ptr->list);
8041             }
8042             else
8043                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8044         }
8045         else
8046             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8047
8048         ptr++;
8049     }
8050
8051     IXMLDOMDocument2_Release(doc);
8052     free_bstrs();
8053 }
8054
8055 static void test_splitText(void)
8056 {
8057     IXMLDOMCDATASection *cdata;
8058     IXMLDOMElement *root;
8059     IXMLDOMDocument *doc;
8060     IXMLDOMText *text, *text2;
8061     IXMLDOMNode *node;
8062     VARIANT var;
8063     VARIANT_BOOL success;
8064     LONG length;
8065     HRESULT hr;
8066
8067     doc = create_document(&IID_IXMLDOMDocument);
8068     if (!doc) return;
8069
8070     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8071     ok(hr == S_OK, "got 0x%08x\n", hr);
8072
8073     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8074     ok(hr == S_OK, "got 0x%08x\n", hr);
8075
8076     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8077     ok(hr == S_OK, "got 0x%08x\n", hr);
8078
8079     V_VT(&var) = VT_EMPTY;
8080     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8081     ok(hr == S_OK, "got 0x%08x\n", hr);
8082
8083     length = 0;
8084     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8085     ok(hr == S_OK, "got 0x%08x\n", hr);
8086     ok(length > 0, "got %d\n", length);
8087
8088     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8089     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8090
8091     text = (void*)0xdeadbeef;
8092     /* negative offset */
8093     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8094     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8095     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8096
8097     text = (void*)0xdeadbeef;
8098     /* offset outside data */
8099     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8100     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8101     ok(text == 0, "got %p\n", text);
8102
8103     text = (void*)0xdeadbeef;
8104     /* offset outside data */
8105     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8106     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8107     ok(text == 0, "got %p\n", text);
8108
8109     /* no empty node created */
8110     node = (void*)0xdeadbeef;
8111     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8112     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8113     ok(node == 0, "got %p\n", text);
8114
8115     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8116     ok(hr == S_OK, "got 0x%08x\n", hr);
8117
8118     length = 0;
8119     hr = IXMLDOMText_get_length(text, &length);
8120     ok(hr == S_OK, "got 0x%08x\n", hr);
8121     ok(length == 7, "got %d\n", length);
8122
8123     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8124     ok(hr == S_OK, "got 0x%08x\n", hr);
8125     IXMLDOMNode_Release(node);
8126
8127     /* split new text node */
8128     hr = IXMLDOMText_get_length(text, &length);
8129     ok(hr == S_OK, "got 0x%08x\n", hr);
8130
8131     node = (void*)0xdeadbeef;
8132     hr = IXMLDOMText_get_nextSibling(text, &node);
8133     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8134     ok(node == 0, "got %p\n", text);
8135
8136     hr = IXMLDOMText_splitText(text, 0, NULL);
8137     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8138
8139     text2 = (void*)0xdeadbeef;
8140     /* negative offset */
8141     hr = IXMLDOMText_splitText(text, -1, &text2);
8142     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8143     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8144
8145     text2 = (void*)0xdeadbeef;
8146     /* offset outside data */
8147     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8148     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8149     ok(text2 == 0, "got %p\n", text2);
8150
8151     text2 = (void*)0xdeadbeef;
8152     /* offset outside data */
8153     hr = IXMLDOMText_splitText(text, length, &text2);
8154     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8155     ok(text2 == 0, "got %p\n", text);
8156
8157     text2 = 0;
8158     hr = IXMLDOMText_splitText(text, 4, &text2);
8159     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8160     if (text2) IXMLDOMText_Release(text2);
8161
8162     node = 0;
8163     hr = IXMLDOMText_get_nextSibling(text, &node);
8164     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8165     if (node) IXMLDOMNode_Release(node);
8166
8167     IXMLDOMText_Release(text);
8168     IXMLDOMElement_Release(root);
8169     IXMLDOMCDATASection_Release(cdata);
8170     free_bstrs();
8171 }
8172
8173 typedef struct {
8174     const char *name;
8175     const char *uri;
8176     HRESULT hr;
8177 } ns_item_t;
8178
8179 /* default_ns_doc used */
8180 static const ns_item_t qualified_item_tests[] = {
8181     { "xml:lang", NULL, S_FALSE },
8182     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8183     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8184     { "ns:b", NULL, S_FALSE },
8185     { "ns:b", "nshref", S_FALSE },
8186     { "b", "nshref", S_OK },
8187     { "d", NULL, S_OK },
8188     { NULL }
8189 };
8190
8191 static const ns_item_t named_item_tests[] = {
8192     { "xml:lang", NULL, S_OK },
8193     { "lang", NULL, S_FALSE },
8194     { "ns:b", NULL, S_OK },
8195     { "b", NULL, S_FALSE },
8196     { "d", NULL, S_OK },
8197     { NULL }
8198 };
8199
8200 static void test_getQualifiedItem(void)
8201 {
8202     IXMLDOMNode *pr_node, *node;
8203     IXMLDOMNodeList *root_list;
8204     IXMLDOMNamedNodeMap *map;
8205     IXMLDOMElement *element;
8206     const ns_item_t* ptr;
8207     IXMLDOMDocument *doc;
8208     VARIANT_BOOL b;
8209     HRESULT hr;
8210     LONG len;
8211
8212     doc = create_document(&IID_IXMLDOMDocument);
8213     if (!doc) return;
8214
8215     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8216     EXPECT_HR(hr, S_OK);
8217     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8218
8219     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8220     EXPECT_HR(hr, S_OK);
8221
8222     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8223     EXPECT_HR(hr, S_OK);
8224
8225     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8226     EXPECT_HR(hr, S_OK);
8227     IXMLDOMNodeList_Release(root_list);
8228
8229     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8230     EXPECT_HR(hr, S_OK);
8231     IXMLDOMNode_Release(pr_node);
8232
8233     len = 0;
8234     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8235     EXPECT_HR(hr, S_OK);
8236     ok( len == 3, "length %d\n", len);
8237
8238     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8239     EXPECT_HR(hr, E_INVALIDARG);
8240
8241     node = (void*)0xdeadbeef;
8242     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8243     EXPECT_HR(hr, E_INVALIDARG);
8244     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8245
8246     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8247     EXPECT_HR(hr, E_INVALIDARG);
8248
8249     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8250     EXPECT_HR(hr, S_OK);
8251
8252     IXMLDOMNode_Release(node);
8253     IXMLDOMNamedNodeMap_Release(map);
8254     IXMLDOMElement_Release(element);
8255
8256     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8257     EXPECT_HR(hr, S_OK);
8258
8259     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8260     EXPECT_HR(hr, S_OK);
8261
8262     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8263     EXPECT_HR(hr, S_OK);
8264     IXMLDOMNode_Release(node);
8265
8266     hr = IXMLDOMElement_get_attributes(element, &map);
8267     EXPECT_HR(hr, S_OK);
8268
8269     ptr = qualified_item_tests;
8270     while (ptr->name)
8271     {
8272        node = (void*)0xdeadbeef;
8273        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8274        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8275        if (hr == S_OK)
8276            IXMLDOMNode_Release(node);
8277        else
8278            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8279        ptr++;
8280     }
8281
8282     ptr = named_item_tests;
8283     while (ptr->name)
8284     {
8285        node = (void*)0xdeadbeef;
8286        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8287        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8288        if (hr == S_OK)
8289            IXMLDOMNode_Release(node);
8290        else
8291            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8292        ptr++;
8293     }
8294
8295     IXMLDOMNamedNodeMap_Release(map);
8296
8297     IXMLDOMElement_Release(element);
8298     IXMLDOMDocument_Release(doc);
8299     free_bstrs();
8300 }
8301
8302 static void test_removeQualifiedItem(void)
8303 {
8304     IXMLDOMDocument *doc;
8305     IXMLDOMElement *element;
8306     IXMLDOMNode *pr_node, *node;
8307     IXMLDOMNodeList *root_list;
8308     IXMLDOMNamedNodeMap *map;
8309     VARIANT_BOOL b;
8310     LONG len;
8311     HRESULT hr;
8312
8313     doc = create_document(&IID_IXMLDOMDocument);
8314     if (!doc) return;
8315
8316     hr = IXMLDOMDocument_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, &element);
8321     ok( hr == S_OK, "ret %08x\n", hr);
8322
8323     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8324     ok( hr == S_OK, "ret %08x\n", hr);
8325
8326     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8327     ok( hr == S_OK, "ret %08x\n", hr);
8328     IXMLDOMNodeList_Release(root_list);
8329
8330     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8331     ok( hr == S_OK, "ret %08x\n", hr);
8332     IXMLDOMNode_Release(pr_node);
8333
8334     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8335     ok( hr == S_OK, "ret %08x\n", hr);
8336     ok( len == 3, "length %d\n", len);
8337
8338     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8339     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8340
8341     node = (void*)0xdeadbeef;
8342     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8343     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8344     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8345
8346     /* out pointer is optional */
8347     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8348     ok( hr == S_OK, "ret %08x\n", hr);
8349
8350     /* already removed */
8351     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8352     ok( hr == S_FALSE, "ret %08x\n", hr);
8353
8354     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8355     ok( hr == S_OK, "ret %08x\n", hr);
8356     IXMLDOMNode_Release(node);
8357
8358     IXMLDOMNamedNodeMap_Release( map );
8359     IXMLDOMElement_Release( element );
8360     IXMLDOMDocument_Release( doc );
8361     free_bstrs();
8362 }
8363
8364 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8365 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8366 {
8367     VARIANT_BOOL b;
8368     VARIANT var;
8369     HRESULT hr;
8370
8371     VariantInit(&var);
8372     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8373     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8374     VariantClear(&var);
8375
8376     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8377     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8378     VariantClear(&var);
8379
8380     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8381     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8382
8383     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8384     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8385     VariantClear(&var);
8386 }
8387
8388 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8389 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8390 {
8391     VARIANT_BOOL b;
8392     VARIANT var;
8393
8394     VariantInit(&var);
8395     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8396     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8397     VariantClear(&var);
8398
8399     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8400     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8401     VariantClear(&var);
8402
8403     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8404     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8405
8406     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8407     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8408     VariantClear(&var);
8409 }
8410
8411 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8412 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8413 {
8414     VARIANT var;
8415
8416     VariantInit(&var);
8417     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8418     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8419     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8420     V_VT(&var) = VT_DISPATCH;
8421     V_DISPATCH(&var) = NULL;
8422     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8423     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8424     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8425     VariantClear(&var);
8426 }
8427
8428 #define unset_props(doc) _unset_props(__LINE__, doc)
8429 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8430 {
8431     VARIANT var;
8432
8433     VariantInit(&var);
8434     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8435     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8436     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8437     V_VT(&var) = VT_NULL;
8438     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8439     VariantClear(&var);
8440 }
8441
8442 static void test_get_ownerDocument(void)
8443 {
8444     IXMLDOMDocument *doc1, *doc2, *doc3;
8445     IXMLDOMDocument2 *doc, *doc_owner;
8446     IXMLDOMNode *node;
8447     IXMLDOMSchemaCollection *cache;
8448     VARIANT_BOOL b;
8449     VARIANT var;
8450
8451     doc = create_document(&IID_IXMLDOMDocument2);
8452     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8453     if (!doc || !cache)
8454     {
8455         if (doc) IXMLDOMDocument2_Release(doc);
8456         if (cache) IXMLDOMSchemaCollection_Release(cache);
8457         return;
8458     }
8459
8460     VariantInit(&var);
8461
8462     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8463     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8464
8465     check_default_props(doc);
8466
8467     /* set properties and check that new instances use them */
8468     set_props(doc, cache);
8469     check_set_props(doc);
8470
8471     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8472     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8473
8474     /* new interface keeps props */
8475     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8476     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8477     check_set_props(doc_owner);
8478     IXMLDOMDocument2_Release(doc_owner);
8479
8480     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8481     IXMLDOMNode_Release(node);
8482
8483     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8484
8485     /* reload */
8486     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8487     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8488
8489     /* properties retained even after reload */
8490     check_set_props(doc);
8491
8492     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8493     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8494     IXMLDOMNode_Release(node);
8495
8496     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8497     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8498     check_set_props(doc_owner);
8499
8500     /* changing properties for one instance changes them for all */
8501     unset_props(doc_owner);
8502     check_default_props(doc_owner);
8503     check_default_props(doc);
8504
8505     IXMLDOMSchemaCollection_Release(cache);
8506     IXMLDOMDocument_Release(doc1);
8507     IXMLDOMDocument_Release(doc2);
8508     IXMLDOMDocument_Release(doc3);
8509     IXMLDOMDocument2_Release(doc);
8510     IXMLDOMDocument2_Release(doc_owner);
8511     free_bstrs();
8512 }
8513
8514 static void test_setAttributeNode(void)
8515 {
8516     IXMLDOMDocument *doc, *doc2;
8517     IXMLDOMElement *elem, *elem2;
8518     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8519     VARIANT_BOOL b;
8520     HRESULT hr;
8521     VARIANT v;
8522     BSTR str;
8523     ULONG ref1, ref2;
8524
8525     doc = create_document(&IID_IXMLDOMDocument);
8526     if (!doc) return;
8527
8528     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8529     ok( hr == S_OK, "loadXML failed\n");
8530     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8531
8532     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8533     ok( hr == S_OK, "got 0x%08x\n", hr);
8534
8535     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8536     ok( hr == S_OK, "got 0x%08x\n", hr);
8537     ok( elem2 != elem, "got same instance\n");
8538
8539     ret_attr = (void*)0xdeadbeef;
8540     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8541     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8542     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8543
8544     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8545     ok( hr == S_OK, "got 0x%08x\n", hr);
8546
8547     ref1 = IXMLDOMElement_AddRef(elem);
8548     IXMLDOMElement_Release(elem);
8549
8550     ret_attr = (void*)0xdeadbeef;
8551     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8552     ok( hr == S_OK, "got 0x%08x\n", hr);
8553     ok( ret_attr == NULL, "got %p\n", ret_attr);
8554
8555     /* no reference added */
8556     ref2 = IXMLDOMElement_AddRef(elem);
8557     IXMLDOMElement_Release(elem);
8558     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8559
8560     EXPECT_CHILDREN(elem);
8561     EXPECT_CHILDREN(elem2);
8562
8563     IXMLDOMElement_Release(elem2);
8564
8565     attr2 = NULL;
8566     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8567     ok( hr == S_OK, "got 0x%08x\n", hr);
8568     ok( attr2 != attr, "got same instance %p\n", attr2);
8569     IXMLDOMAttribute_Release(attr2);
8570
8571     /* try to add it another time */
8572     ret_attr = (void*)0xdeadbeef;
8573     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8574     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8575     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8576
8577     IXMLDOMElement_Release(elem);
8578
8579     /* initially used element is released, attribute still 'has' a container */
8580     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8581     ok( hr == S_OK, "got 0x%08x\n", hr);
8582     ret_attr = (void*)0xdeadbeef;
8583     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8584     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8585     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8586     IXMLDOMElement_Release(elem);
8587
8588     /* add attribute already attached to another document */
8589     doc2 = create_document(&IID_IXMLDOMDocument);
8590
8591     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8592     ok( hr == S_OK, "loadXML failed\n");
8593     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8594
8595     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8596     ok( hr == S_OK, "got 0x%08x\n", hr);
8597     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8598     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8599     IXMLDOMElement_Release(elem);
8600
8601     IXMLDOMAttribute_Release(attr);
8602
8603     /* create element, add attribute, see if it's copied or linked */
8604     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8605     ok( hr == S_OK, "got 0x%08x\n", hr);
8606
8607     attr = NULL;
8608     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8609     ok(hr == S_OK, "got 0x%08x\n", hr);
8610     ok(attr != NULL, "got %p\n", attr);
8611
8612     ref1 = IXMLDOMAttribute_AddRef(attr);
8613     IXMLDOMAttribute_Release(attr);
8614
8615     V_VT(&v) = VT_BSTR;
8616     V_BSTR(&v) = _bstr_("attrvalue1");
8617     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8618     ok( hr == S_OK, "got 0x%08x\n", hr);
8619
8620     str = NULL;
8621     hr = IXMLDOMAttribute_get_xml(attr, &str);
8622     ok( hr == S_OK, "got 0x%08x\n", hr);
8623     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8624         "got %s\n", wine_dbgstr_w(str));
8625     SysFreeString(str);
8626
8627     ret_attr = (void*)0xdeadbeef;
8628     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8629     ok(hr == S_OK, "got 0x%08x\n", hr);
8630     ok(ret_attr == NULL, "got %p\n", ret_attr);
8631
8632     /* attribute reference increased */
8633     ref2 = IXMLDOMAttribute_AddRef(attr);
8634     IXMLDOMAttribute_Release(attr);
8635     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8636
8637     hr = IXMLDOMElement_get_xml(elem, &str);
8638     ok( hr == S_OK, "got 0x%08x\n", hr);
8639     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8640         "got %s\n", wine_dbgstr_w(str));
8641     SysFreeString(str);
8642
8643     V_VT(&v) = VT_BSTR;
8644     V_BSTR(&v) = _bstr_("attrvalue2");
8645     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8646     ok( hr == S_OK, "got 0x%08x\n", hr);
8647
8648     hr = IXMLDOMElement_get_xml(elem, &str);
8649     ok( hr == S_OK, "got 0x%08x\n", hr);
8650     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8651         "got %s\n", wine_dbgstr_w(str));
8652     SysFreeString(str);
8653
8654     IXMLDOMElement_Release(elem);
8655     IXMLDOMAttribute_Release(attr);
8656     IXMLDOMDocument_Release(doc2);
8657     IXMLDOMDocument_Release(doc);
8658     free_bstrs();
8659 }
8660
8661 static void test_put_dataType(void)
8662 {
8663     IXMLDOMCDATASection *cdata;
8664     IXMLDOMDocument *doc;
8665     VARIANT_BOOL b;
8666     HRESULT hr;
8667
8668     doc = create_document(&IID_IXMLDOMDocument);
8669     if (!doc) return;
8670
8671     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8672     ok( hr == S_OK, "loadXML failed\n");
8673     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8674
8675     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
8676     ok( hr == S_OK, "got 0x%08x\n", hr);
8677     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
8678     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8679     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
8680     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8681     IXMLDOMCDATASection_Release(cdata);
8682
8683     IXMLDOMDocument_Release(doc);
8684     free_bstrs();
8685 }
8686
8687 static void test_createNode(void)
8688 {
8689     IXMLDOMDocument *doc;
8690     IXMLDOMElement *elem;
8691     IXMLDOMNode *node;
8692     VARIANT v, var;
8693     BSTR prefix, str;
8694     HRESULT hr;
8695     ULONG ref;
8696
8697     doc = create_document(&IID_IXMLDOMDocument);
8698     if (!doc) return;
8699
8700     EXPECT_REF(doc, 1);
8701
8702     /* reference count tests */
8703     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8704     ok( hr == S_OK, "got 0x%08x\n", hr);
8705
8706     /* initial reference is 2 */
8707 todo_wine {
8708     EXPECT_REF(elem, 2);
8709     ref = IXMLDOMElement_Release(elem);
8710     ok(ref == 1, "got %d\n", ref);
8711     /* it's released already, attempt to release now will crash it */
8712 }
8713
8714     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8715     ok( hr == S_OK, "got 0x%08x\n", hr);
8716     todo_wine EXPECT_REF(elem, 2);
8717     IXMLDOMDocument_Release(doc);
8718     todo_wine EXPECT_REF(elem, 2);
8719     IXMLDOMElement_Release(elem);
8720
8721     doc = create_document(&IID_IXMLDOMDocument);
8722
8723     /* NODE_ELEMENT nodes */
8724     /* 1. specified namespace */
8725     V_VT(&v) = VT_I4;
8726     V_I4(&v) = NODE_ELEMENT;
8727
8728     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8729     ok( hr == S_OK, "got 0x%08x\n", hr);
8730     prefix = NULL;
8731     hr = IXMLDOMNode_get_prefix(node, &prefix);
8732     ok( hr == S_OK, "got 0x%08x\n", hr);
8733     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8734     SysFreeString(prefix);
8735     IXMLDOMNode_Release(node);
8736
8737     /* 2. default namespace */
8738     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8739     ok( hr == S_OK, "got 0x%08x\n", hr);
8740     prefix = (void*)0xdeadbeef;
8741     hr = IXMLDOMNode_get_prefix(node, &prefix);
8742     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8743     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8744     /* check dump */
8745     hr = IXMLDOMNode_get_xml(node, &str);
8746     ok( hr == S_OK, "got 0x%08x\n", hr);
8747     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8748         "got %s\n", wine_dbgstr_w(str));
8749     SysFreeString(str);
8750
8751     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8752     ok( hr == S_OK, "got 0x%08x\n", hr);
8753
8754     V_VT(&var) = VT_BSTR;
8755     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8756     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8757     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8758
8759     str = NULL;
8760     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8761     ok( hr == S_OK, "got 0x%08x\n", hr);
8762     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8763     SysFreeString(str);
8764
8765     IXMLDOMElement_Release(elem);
8766     IXMLDOMNode_Release(node);
8767
8768     IXMLDOMDocument_Release(doc);
8769     free_bstrs();
8770 }
8771
8772 static const char get_prefix_doc[] =
8773     "<?xml version=\"1.0\" ?>"
8774     "<a xmlns:ns1=\"ns1 href\" />";
8775
8776 static void test_get_prefix(void)
8777 {
8778     IXMLDOMDocumentFragment *fragment;
8779     IXMLDOMCDATASection *cdata;
8780     IXMLDOMElement *element;
8781     IXMLDOMComment *comment;
8782     IXMLDOMDocument *doc;
8783     VARIANT_BOOL b;
8784     HRESULT hr;
8785     BSTR str;
8786
8787     doc = create_document(&IID_IXMLDOMDocument);
8788     if (!doc) return;
8789
8790     /* nodes that can't support prefix */
8791     /* 1. document */
8792     str = (void*)0xdeadbeef;
8793     hr = IXMLDOMDocument_get_prefix(doc, &str);
8794     EXPECT_HR(hr, S_FALSE);
8795     ok(str == NULL, "got %p\n", str);
8796
8797     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8798     EXPECT_HR(hr, E_INVALIDARG);
8799
8800     /* 2. cdata */
8801     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8802     ok(hr == S_OK, "got %08x\n", hr );
8803
8804     str = (void*)0xdeadbeef;
8805     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8806     ok(hr == S_FALSE, "got %08x\n", hr);
8807     ok( str == 0, "got %p\n", str);
8808
8809     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8810     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8811     IXMLDOMCDATASection_Release(cdata);
8812
8813     /* 3. comment */
8814     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8815     ok(hr == S_OK, "got %08x\n", hr );
8816
8817     str = (void*)0xdeadbeef;
8818     hr = IXMLDOMComment_get_prefix(comment, &str);
8819     ok(hr == S_FALSE, "got %08x\n", hr);
8820     ok( str == 0, "got %p\n", str);
8821
8822     hr = IXMLDOMComment_get_prefix(comment, NULL);
8823     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8824     IXMLDOMComment_Release(comment);
8825
8826     /* 4. fragment */
8827     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8828     ok(hr == S_OK, "got %08x\n", hr );
8829
8830     str = (void*)0xdeadbeef;
8831     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8832     ok(hr == S_FALSE, "got %08x\n", hr);
8833     ok( str == 0, "got %p\n", str);
8834
8835     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8836     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8837     IXMLDOMDocumentFragment_Release(fragment);
8838
8839     /* no prefix */
8840     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8841     ok( hr == S_OK, "got 0x%08x\n", hr);
8842
8843     hr = IXMLDOMElement_get_prefix(element, NULL);
8844     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8845
8846     str = (void*)0xdeadbeef;
8847     hr = IXMLDOMElement_get_prefix(element, &str);
8848     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8849     ok( str == 0, "got %p\n", str);
8850
8851     IXMLDOMElement_Release(element);
8852
8853     /* with prefix */
8854     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8855     ok( hr == S_OK, "got 0x%08x\n", hr);
8856
8857     str = (void*)0xdeadbeef;
8858     hr = IXMLDOMElement_get_prefix(element, &str);
8859     ok( hr == S_OK, "got 0x%08x\n", hr);
8860     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8861     SysFreeString(str);
8862
8863     str = (void*)0xdeadbeef;
8864     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8865     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8866     ok( str == 0, "got %p\n", str);
8867
8868     IXMLDOMElement_Release(element);
8869
8870     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8871     EXPECT_HR(hr, S_OK);
8872
8873     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8874     EXPECT_HR(hr, S_OK);
8875
8876     str = (void*)0xdeadbeef;
8877     hr = IXMLDOMElement_get_prefix(element, &str);
8878     EXPECT_HR(hr, S_FALSE);
8879     ok(str == NULL, "got %p\n", str);
8880
8881     str = (void*)0xdeadbeef;
8882     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8883     EXPECT_HR(hr, S_FALSE);
8884     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8885
8886     IXMLDOMDocument_Release(doc);
8887     free_bstrs();
8888 }
8889
8890 static void test_selectSingleNode(void)
8891 {
8892     IXMLDOMDocument *doc;
8893     IXMLDOMNodeList *list;
8894     IXMLDOMNode *node;
8895     VARIANT_BOOL b;
8896     HRESULT hr;
8897     LONG len;
8898
8899     doc = create_document(&IID_IXMLDOMDocument);
8900     if (!doc) return;
8901
8902     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8903     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8904
8905     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8906     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8907
8908     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8909     ok( hr == S_OK, "loadXML failed\n");
8910     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8911
8912     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8913     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8914
8915     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8916     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8917
8918     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8919     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8920
8921     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8922     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8923
8924     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8925     ok(hr == S_OK, "got 0x%08x\n", hr);
8926     IXMLDOMNode_Release(node);
8927
8928     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8929     ok(hr == S_OK, "got 0x%08x\n", hr);
8930     IXMLDOMNodeList_Release(list);
8931
8932     list = (void*)0xdeadbeef;
8933     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8934     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8935     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8936
8937     node = (void*)0xdeadbeef;
8938     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8939     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8940     ok(node == 0, "got %p\n", node);
8941
8942     list = (void*)0xdeadbeef;
8943     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8944     ok(hr == S_OK, "got 0x%08x\n", hr);
8945     len = 1;
8946     hr = IXMLDOMNodeList_get_length(list, &len);
8947     ok(hr == S_OK, "got 0x%08x\n", hr);
8948     ok(len == 0, "got %d\n", len);
8949     IXMLDOMNodeList_Release(list);
8950
8951     IXMLDOMDocument_Release(doc);
8952     free_bstrs();
8953 }
8954
8955 static void test_events(void)
8956 {
8957     IConnectionPointContainer *conn;
8958     IConnectionPoint *point;
8959     IXMLDOMDocument *doc;
8960     HRESULT hr;
8961     VARIANT v;
8962     IDispatch *event;
8963
8964     doc = create_document(&IID_IXMLDOMDocument);
8965     if (!doc) return;
8966
8967     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8968     ok(hr == S_OK, "got 0x%08x\n", hr);
8969
8970     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8971     ok(hr == S_OK, "got 0x%08x\n", hr);
8972     IConnectionPoint_Release(point);
8973     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8974     ok(hr == S_OK, "got 0x%08x\n", hr);
8975     IConnectionPoint_Release(point);
8976     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8977     ok(hr == S_OK, "got 0x%08x\n", hr);
8978     IConnectionPoint_Release(point);
8979
8980     IConnectionPointContainer_Release(conn);
8981
8982     /* ready state callback */
8983     VariantInit(&v);
8984     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8985     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8986
8987     event = create_dispevent();
8988     V_VT(&v) = VT_UNKNOWN;
8989     V_UNKNOWN(&v) = (IUnknown*)event;
8990
8991     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8992     ok(hr == S_OK, "got 0x%08x\n", hr);
8993     EXPECT_REF(event, 2);
8994
8995     V_VT(&v) = VT_DISPATCH;
8996     V_DISPATCH(&v) = event;
8997
8998     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8999     ok(hr == S_OK, "got 0x%08x\n", hr);
9000     EXPECT_REF(event, 2);
9001
9002     /* VT_NULL doesn't reset event handler */
9003     V_VT(&v) = VT_NULL;
9004     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9005     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9006     EXPECT_REF(event, 2);
9007
9008     V_VT(&v) = VT_DISPATCH;
9009     V_DISPATCH(&v) = NULL;
9010
9011     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9012     ok(hr == S_OK, "got 0x%08x\n", hr);
9013     EXPECT_REF(event, 1);
9014
9015     V_VT(&v) = VT_UNKNOWN;
9016     V_DISPATCH(&v) = NULL;
9017     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9018     ok(hr == S_OK, "got 0x%08x\n", hr);
9019
9020     IDispatch_Release(event);
9021
9022     IXMLDOMDocument_Release(doc);
9023 }
9024
9025 static void test_createProcessingInstruction(void)
9026 {
9027     static const WCHAR bodyW[] = {'t','e','s','t',0};
9028     IXMLDOMProcessingInstruction *pi;
9029     IXMLDOMDocument *doc;
9030     WCHAR buff[10];
9031     HRESULT hr;
9032
9033     doc = create_document(&IID_IXMLDOMDocument);
9034     if (!doc) return;
9035
9036     /* test for BSTR handling, pass broken BSTR */
9037     memcpy(&buff[2], bodyW, sizeof(bodyW));
9038     /* just a big length */
9039     *(DWORD*)buff = 0xf0f0;
9040     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9041     ok(hr == S_OK, "got 0x%08x\n", hr);
9042
9043     IXMLDOMProcessingInstruction_Release(pi);
9044     IXMLDOMDocument_Release(doc);
9045 }
9046
9047 static void test_put_nodeTypedValue(void)
9048 {
9049     IXMLDOMDocument *doc;
9050     IXMLDOMElement *elem;
9051     VARIANT type;
9052     HRESULT hr;
9053
9054     doc = create_document(&IID_IXMLDOMDocument);
9055     if (!doc) return;
9056
9057     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9058     ok(hr == S_OK, "got 0x%08x\n", hr);
9059
9060     V_VT(&type) = VT_EMPTY;
9061     hr = IXMLDOMElement_get_dataType(elem, &type);
9062     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9063     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9064
9065     /* set typed value for untyped node */
9066     V_VT(&type) = VT_I1;
9067     V_I1(&type) = 1;
9068     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9069     ok(hr == S_OK, "got 0x%08x\n", hr);
9070
9071     V_VT(&type) = VT_EMPTY;
9072     hr = IXMLDOMElement_get_dataType(elem, &type);
9073     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9074     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9075
9076     /* no type info stored */
9077     V_VT(&type) = VT_EMPTY;
9078     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9079     ok(hr == S_OK, "got 0x%08x\n", hr);
9080     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9081     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9082        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9083     VariantClear(&type);
9084
9085     IXMLDOMElement_Release(elem);
9086     IXMLDOMDocument_Release(doc);
9087     free_bstrs();
9088 }
9089
9090 static void test_get_xml(void)
9091 {
9092     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9093     static const char fooA[] = "<foo/>";
9094     IXMLDOMProcessingInstruction *pi;
9095     IXMLDOMNode *first;
9096     IXMLDOMElement *elem = NULL;
9097     IXMLDOMDocument *doc;
9098     VARIANT_BOOL b;
9099     VARIANT v;
9100     BSTR xml;
9101     HRESULT hr;
9102
9103     doc = create_document(&IID_IXMLDOMDocument);
9104     if (!doc) return;
9105
9106     b = VARIANT_TRUE;
9107     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9108     ok(hr == S_OK, "got 0x%08x\n", hr);
9109     ok( b == VARIANT_TRUE, "got %d\n", b);
9110
9111     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9112                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9113     ok(hr == S_OK, "got 0x%08x\n", hr);
9114
9115     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9116     ok(hr == S_OK, "got 0x%08x\n", hr);
9117
9118     V_UNKNOWN(&v) = (IUnknown*)first;
9119     V_VT(&v) = VT_UNKNOWN;
9120
9121     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9122     ok(hr == S_OK, "got 0x%08x\n", hr);
9123
9124     IXMLDOMProcessingInstruction_Release(pi);
9125     IXMLDOMNode_Release(first);
9126
9127     hr = IXMLDOMDocument_get_xml(doc, &xml);
9128     ok(hr == S_OK, "got 0x%08x\n", hr);
9129
9130     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9131         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9132     SysFreeString(xml);
9133
9134     IXMLDOMDocument_Release(doc);
9135
9136     doc = create_document(&IID_IXMLDOMDocument);
9137
9138     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9139     ok(hr == S_OK, "got 0x%08x\n", hr);
9140
9141     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9142     ok(hr == S_OK, "got 0x%08x\n", hr);
9143
9144     hr = IXMLDOMDocument_get_xml(doc, &xml);
9145     ok(hr == S_OK, "got 0x%08x\n", hr);
9146
9147     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9148         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9149     SysFreeString(xml);
9150
9151     IXMLDOMElement_Release(elem);
9152     IXMLDOMDocument_Release(doc);
9153
9154     free_bstrs();
9155 }
9156
9157 static void test_xsltemplate(void)
9158 {
9159     IXSLTemplate *template;
9160     IXSLProcessor *processor;
9161     IXMLDOMDocument *doc, *doc2;
9162     IStream *stream;
9163     VARIANT_BOOL b;
9164     HRESULT hr;
9165     ULONG ref1, ref2;
9166     VARIANT v;
9167
9168     template = create_xsltemplate(&IID_IXSLTemplate);
9169     if (!template) return;
9170
9171     /* works as reset */
9172     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9173     ok(hr == S_OK, "got 0x%08x\n", hr);
9174
9175     doc = create_document(&IID_IXMLDOMDocument);
9176
9177     b = VARIANT_TRUE;
9178     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9179     ok(hr == S_OK, "got 0x%08x\n", hr);
9180     ok( b == VARIANT_TRUE, "got %d\n", b);
9181
9182     /* putref with non-xsl document */
9183     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9184     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9185
9186     b = VARIANT_TRUE;
9187     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9188     ok(hr == S_OK, "got 0x%08x\n", hr);
9189     ok( b == VARIANT_TRUE, "got %d\n", b);
9190
9191     /* not a freethreaded document */
9192     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9193     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9194
9195     IXMLDOMDocument_Release(doc);
9196
9197     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9198     if (hr != S_OK)
9199     {
9200         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9201         IXSLTemplate_Release(template);
9202         return;
9203     }
9204
9205     b = VARIANT_TRUE;
9206     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9207     ok(hr == S_OK, "got 0x%08x\n", hr);
9208     ok( b == VARIANT_TRUE, "got %d\n", b);
9209
9210     /* freethreaded document */
9211     ref1 = IXMLDOMDocument_AddRef(doc);
9212     IXMLDOMDocument_Release(doc);
9213     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9214     ok(hr == S_OK, "got 0x%08x\n", hr);
9215     ref2 = IXMLDOMDocument_AddRef(doc);
9216     IXMLDOMDocument_Release(doc);
9217     ok(ref2 > ref1, "got %d\n", ref2);
9218
9219     /* processor */
9220     hr = IXSLTemplate_createProcessor(template, NULL);
9221     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9222
9223     EXPECT_REF(template, 1);
9224     hr = IXSLTemplate_createProcessor(template, &processor);
9225     ok(hr == S_OK, "got 0x%08x\n", hr);
9226     EXPECT_REF(template, 2);
9227
9228     /* input no set yet */
9229     V_VT(&v) = VT_BSTR;
9230     V_BSTR(&v) = NULL;
9231     hr = IXSLProcessor_get_input(processor, &v);
9232 todo_wine {
9233     ok(hr == S_OK, "got 0x%08x\n", hr);
9234     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9235 }
9236
9237     hr = IXSLProcessor_get_output(processor, NULL);
9238     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9239
9240     /* reset before it was set */
9241     V_VT(&v) = VT_EMPTY;
9242     hr = IXSLProcessor_put_output(processor, v);
9243     ok(hr == S_OK, "got 0x%08x\n", hr);
9244
9245     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9246     EXPECT_REF(stream, 1);
9247
9248     V_VT(&v) = VT_UNKNOWN;
9249     V_UNKNOWN(&v) = (IUnknown*)stream;
9250     hr = IXSLProcessor_put_output(processor, v);
9251     ok(hr == S_OK, "got 0x%08x\n", hr);
9252
9253     /* it seems processor grabs 2 references */
9254     todo_wine EXPECT_REF(stream, 3);
9255
9256     V_VT(&v) = VT_EMPTY;
9257     hr = IXSLProcessor_get_output(processor, &v);
9258     ok(hr == S_OK, "got 0x%08x\n", hr);
9259     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9260     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9261
9262     todo_wine EXPECT_REF(stream, 4);
9263     VariantClear(&v);
9264
9265     hr = IXSLProcessor_transform(processor, NULL);
9266     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9267
9268     /* reset and check stream refcount */
9269     V_VT(&v) = VT_EMPTY;
9270     hr = IXSLProcessor_put_output(processor, v);
9271     ok(hr == S_OK, "got 0x%08x\n", hr);
9272
9273     EXPECT_REF(stream, 1);
9274
9275     IStream_Release(stream);
9276
9277     /* no output interface set, check output */
9278     doc2 = create_document(&IID_IXMLDOMDocument);
9279
9280     b = VARIANT_TRUE;
9281     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9282     ok(hr == S_OK, "got 0x%08x\n", hr);
9283     ok( b == VARIANT_TRUE, "got %d\n", b);
9284
9285     V_VT(&v) = VT_UNKNOWN;
9286     V_UNKNOWN(&v) = (IUnknown*)doc2;
9287     hr = IXSLProcessor_put_input(processor, v);
9288     ok(hr == S_OK, "got 0x%08x\n", hr);
9289
9290     hr = IXSLProcessor_transform(processor, &b);
9291     ok(hr == S_OK, "got 0x%08x\n", hr);
9292
9293     V_VT(&v) = VT_EMPTY;
9294     hr = IXSLProcessor_get_output(processor, &v);
9295     ok(hr == S_OK, "got 0x%08x\n", hr);
9296     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9297     /* we currently output one '\n' instead of empty string */
9298     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9299     IXMLDOMDocument_Release(doc2);
9300     VariantClear(&v);
9301
9302     IXSLProcessor_Release(processor);
9303
9304     /* drop reference */
9305     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9306     ok(hr == S_OK, "got 0x%08x\n", hr);
9307     ref2 = IXMLDOMDocument_AddRef(doc);
9308     IXMLDOMDocument_Release(doc);
9309     ok(ref2 == ref1, "got %d\n", ref2);
9310
9311     IXMLDOMDocument_Release(doc);
9312     IXSLTemplate_Release(template);
9313     free_bstrs();
9314 }
9315
9316 static void test_insertBefore(void)
9317 {
9318     IXMLDOMDocument *doc, *doc2;
9319     IXMLDOMAttribute *attr;
9320     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9321     IXMLDOMNode *node, *newnode;
9322     HRESULT hr;
9323     VARIANT v;
9324     BSTR p;
9325
9326     doc = create_document(&IID_IXMLDOMDocument);
9327
9328     /* insertBefore behaviour for attribute node */
9329     V_VT(&v) = VT_I4;
9330     V_I4(&v) = NODE_ATTRIBUTE;
9331
9332     attr = NULL;
9333     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9334     ok(hr == S_OK, "got 0x%08x\n", hr);
9335     ok(attr != NULL, "got %p\n", attr);
9336
9337     /* attribute to attribute */
9338     V_VT(&v) = VT_I4;
9339     V_I4(&v) = NODE_ATTRIBUTE;
9340     newnode = NULL;
9341     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9342     ok(hr == S_OK, "got 0x%08x\n", hr);
9343     ok(newnode != NULL, "got %p\n", newnode);
9344
9345     V_VT(&v) = VT_NULL;
9346     node = (void*)0xdeadbeef;
9347     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9348     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9349     ok(node == NULL, "got %p\n", node);
9350
9351     V_VT(&v) = VT_UNKNOWN;
9352     V_UNKNOWN(&v) = (IUnknown*)attr;
9353     node = (void*)0xdeadbeef;
9354     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9355     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9356     ok(node == NULL, "got %p\n", node);
9357     IXMLDOMNode_Release(newnode);
9358
9359     /* cdata to attribute */
9360     V_VT(&v) = VT_I4;
9361     V_I4(&v) = NODE_CDATA_SECTION;
9362     newnode = NULL;
9363     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9364     ok(hr == S_OK, "got 0x%08x\n", hr);
9365     ok(newnode != NULL, "got %p\n", newnode);
9366
9367     V_VT(&v) = VT_NULL;
9368     node = (void*)0xdeadbeef;
9369     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9370     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9371     ok(node == NULL, "got %p\n", node);
9372     IXMLDOMNode_Release(newnode);
9373
9374     /* comment to attribute */
9375     V_VT(&v) = VT_I4;
9376     V_I4(&v) = NODE_COMMENT;
9377     newnode = NULL;
9378     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9379     ok(hr == S_OK, "got 0x%08x\n", hr);
9380     ok(newnode != NULL, "got %p\n", newnode);
9381
9382     V_VT(&v) = VT_NULL;
9383     node = (void*)0xdeadbeef;
9384     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9385     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9386     ok(node == NULL, "got %p\n", node);
9387     IXMLDOMNode_Release(newnode);
9388
9389     /* element to attribute */
9390     V_VT(&v) = VT_I4;
9391     V_I4(&v) = NODE_ELEMENT;
9392     newnode = NULL;
9393     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9394     ok(hr == S_OK, "got 0x%08x\n", hr);
9395     ok(newnode != NULL, "got %p\n", newnode);
9396
9397     V_VT(&v) = VT_NULL;
9398     node = (void*)0xdeadbeef;
9399     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9400     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9401     ok(node == NULL, "got %p\n", node);
9402     IXMLDOMNode_Release(newnode);
9403
9404     /* pi to attribute */
9405     V_VT(&v) = VT_I4;
9406     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9407     newnode = NULL;
9408     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9409     ok(hr == S_OK, "got 0x%08x\n", hr);
9410     ok(newnode != NULL, "got %p\n", newnode);
9411
9412     V_VT(&v) = VT_NULL;
9413     node = (void*)0xdeadbeef;
9414     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9415     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9416     ok(node == NULL, "got %p\n", node);
9417     IXMLDOMNode_Release(newnode);
9418     IXMLDOMAttribute_Release(attr);
9419
9420     /* insertBefore for elements */
9421     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9422     ok(hr == S_OK, "got 0x%08x\n", hr);
9423
9424     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9425     ok(hr == S_OK, "got 0x%08x\n", hr);
9426
9427     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9428     ok(hr == S_OK, "got 0x%08x\n", hr);
9429
9430     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9431     ok(hr == S_OK, "got 0x%08x\n", hr);
9432
9433     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9434     ok(hr == S_OK, "got 0x%08x\n", hr);
9435
9436     EXPECT_NO_CHILDREN(elem1);
9437     EXPECT_NO_CHILDREN(elem2);
9438     EXPECT_NO_CHILDREN(elem3);
9439
9440     todo_wine EXPECT_REF(elem2, 2);
9441
9442     V_VT(&v) = VT_DISPATCH;
9443     V_DISPATCH(&v) = NULL;
9444     node = NULL;
9445     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9446     ok(hr == S_OK, "got 0x%08x\n", hr);
9447     ok(node == (void*)elem4, "got %p\n", node);
9448
9449     EXPECT_CHILDREN(elem1);
9450     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9451     EXPECT_HR(hr, S_OK);
9452     IXMLDOMElement_Release(elem4);
9453
9454     EXPECT_NO_CHILDREN(elem1);
9455
9456     V_VT(&v) = VT_NULL;
9457     node = NULL;
9458     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9459     ok(hr == S_OK, "got 0x%08x\n", hr);
9460     ok(node == (void*)elem2, "got %p\n", node);
9461
9462     EXPECT_CHILDREN(elem1);
9463     todo_wine EXPECT_REF(elem2, 3);
9464     IXMLDOMNode_Release(node);
9465
9466     /* again for already linked node */
9467     V_VT(&v) = VT_NULL;
9468     node = NULL;
9469     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9470     ok(hr == S_OK, "got 0x%08x\n", hr);
9471     ok(node == (void*)elem2, "got %p\n", node);
9472
9473     EXPECT_CHILDREN(elem1);
9474
9475     /* increments each time */
9476     todo_wine EXPECT_REF(elem2, 3);
9477     IXMLDOMNode_Release(node);
9478
9479     /* try to add to another element */
9480     V_VT(&v) = VT_NULL;
9481     node = (void*)0xdeadbeef;
9482     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9483     ok(hr == S_OK, "got 0x%08x\n", hr);
9484     ok(node == (void*)elem2, "got %p\n", node);
9485
9486     EXPECT_CHILDREN(elem3);
9487     EXPECT_NO_CHILDREN(elem1);
9488
9489     IXMLDOMNode_Release(node);
9490
9491     /* cross document case - try to add as child to a node created with other doc */
9492     doc2 = create_document(&IID_IXMLDOMDocument);
9493
9494     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9495     ok(hr == S_OK, "got 0x%08x\n", hr);
9496     todo_wine EXPECT_REF(elem4, 2);
9497
9498     /* same name, another instance */
9499     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9500     ok(hr == S_OK, "got 0x%08x\n", hr);
9501     todo_wine EXPECT_REF(elem5, 2);
9502
9503     todo_wine EXPECT_REF(elem3, 2);
9504     V_VT(&v) = VT_NULL;
9505     node = NULL;
9506     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9507     ok(hr == S_OK, "got 0x%08x\n", hr);
9508     ok(node == (void*)elem4, "got %p\n", node);
9509     todo_wine EXPECT_REF(elem4, 3);
9510     todo_wine EXPECT_REF(elem3, 2);
9511     IXMLDOMNode_Release(node);
9512
9513     V_VT(&v) = VT_NULL;
9514     node = NULL;
9515     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9516     ok(hr == S_OK, "got 0x%08x\n", hr);
9517     ok(node == (void*)elem5, "got %p\n", node);
9518     todo_wine EXPECT_REF(elem4, 2);
9519     todo_wine EXPECT_REF(elem5, 3);
9520     IXMLDOMNode_Release(node);
9521
9522     IXMLDOMDocument_Release(doc2);
9523
9524     IXMLDOMElement_Release(elem1);
9525     IXMLDOMElement_Release(elem2);
9526     IXMLDOMElement_Release(elem3);
9527     IXMLDOMElement_Release(elem4);
9528     IXMLDOMElement_Release(elem5);
9529
9530     /* elements with same default namespace */
9531     V_VT(&v) = VT_I4;
9532     V_I4(&v) = NODE_ELEMENT;
9533     elem1 = NULL;
9534     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9535     ok(hr == S_OK, "got 0x%08x\n", hr);
9536     ok(elem1 != NULL, "got %p\n", elem1);
9537
9538     V_VT(&v) = VT_I4;
9539     V_I4(&v) = NODE_ELEMENT;
9540     elem2 = NULL;
9541     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9542     ok(hr == S_OK, "got 0x%08x\n", hr);
9543     ok(elem2 != NULL, "got %p\n", elem2);
9544
9545     /* check contents so far */
9546     p = NULL;
9547     hr = IXMLDOMElement_get_xml(elem1, &p);
9548     ok(hr == S_OK, "got 0x%08x\n", hr);
9549     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9550     SysFreeString(p);
9551
9552     p = NULL;
9553     hr = IXMLDOMElement_get_xml(elem2, &p);
9554     ok(hr == S_OK, "got 0x%08x\n", hr);
9555     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9556     SysFreeString(p);
9557
9558     V_VT(&v) = VT_NULL;
9559     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9560     ok(hr == S_OK, "got 0x%08x\n", hr);
9561
9562     /* get_xml depends on context, for top node it omits child namespace attribute,
9563        but at child level it's still returned */
9564     p = NULL;
9565     hr = IXMLDOMElement_get_xml(elem1, &p);
9566     ok(hr == S_OK, "got 0x%08x\n", hr);
9567     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9568         "got %s\n", wine_dbgstr_w(p));
9569     SysFreeString(p);
9570
9571     p = NULL;
9572     hr = IXMLDOMElement_get_xml(elem2, &p);
9573     ok(hr == S_OK, "got 0x%08x\n", hr);
9574     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9575     SysFreeString(p);
9576
9577     IXMLDOMElement_Release(elem1);
9578     IXMLDOMElement_Release(elem2);
9579
9580     /* child without default namespace added to node with default namespace */
9581     V_VT(&v) = VT_I4;
9582     V_I4(&v) = NODE_ELEMENT;
9583     elem1 = NULL;
9584     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9585     ok(hr == S_OK, "got 0x%08x\n", hr);
9586     ok(elem1 != NULL, "got %p\n", elem1);
9587
9588     V_VT(&v) = VT_I4;
9589     V_I4(&v) = NODE_ELEMENT;
9590     elem2 = NULL;
9591     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9592     ok(hr == S_OK, "got 0x%08x\n", hr);
9593     ok(elem2 != NULL, "got %p\n", elem2);
9594
9595     EXPECT_REF(elem2, 1);
9596     V_VT(&v) = VT_NULL;
9597     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9598     ok(hr == S_OK, "got 0x%08x\n", hr);
9599     EXPECT_REF(elem2, 1);
9600
9601     p = NULL;
9602     hr = IXMLDOMElement_get_xml(elem2, &p);
9603     ok(hr == S_OK, "got 0x%08x\n", hr);
9604     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9605     SysFreeString(p);
9606
9607     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9608     ok(hr == S_OK, "got 0x%08x\n", hr);
9609
9610     p = NULL;
9611     hr = IXMLDOMElement_get_xml(elem2, &p);
9612     ok(hr == S_OK, "got 0x%08x\n", hr);
9613     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9614     SysFreeString(p);
9615
9616     IXMLDOMElement_Release(elem1);
9617     IXMLDOMElement_Release(elem2);
9618     IXMLDOMDocument_Release(doc);
9619 }
9620
9621 static void test_appendChild(void)
9622 {
9623     IXMLDOMDocument *doc, *doc2;
9624     IXMLDOMElement *elem, *elem2;
9625     HRESULT hr;
9626
9627     doc = create_document(&IID_IXMLDOMDocument);
9628     doc2 = create_document(&IID_IXMLDOMDocument);
9629
9630     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9631     ok(hr == S_OK, "got 0x%08x\n", hr);
9632
9633     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9634     ok(hr == S_OK, "got 0x%08x\n", hr);
9635
9636     EXPECT_REF(doc, 1);
9637     todo_wine EXPECT_REF(elem, 2);
9638     EXPECT_REF(doc2, 1);
9639     todo_wine EXPECT_REF(elem2, 2);
9640     EXPECT_NO_CHILDREN(doc);
9641     EXPECT_NO_CHILDREN(doc2);
9642
9643     /* append from another document */
9644     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9645     ok(hr == S_OK, "got 0x%08x\n", hr);
9646
9647     EXPECT_REF(doc, 1);
9648     todo_wine EXPECT_REF(elem, 2);
9649     EXPECT_REF(doc2, 1);
9650     todo_wine EXPECT_REF(elem2, 2);
9651     EXPECT_NO_CHILDREN(doc);
9652     EXPECT_CHILDREN(doc2);
9653
9654     IXMLDOMElement_Release(elem);
9655     IXMLDOMElement_Release(elem2);
9656     IXMLDOMDocument_Release(doc);
9657     IXMLDOMDocument_Release(doc2);
9658 }
9659
9660 static void test_get_doctype(void)
9661 {
9662     IXMLDOMDocumentType *doctype;
9663     IXMLDOMDocument *doc;
9664     HRESULT hr;
9665
9666     doc = create_document(&IID_IXMLDOMDocument);
9667
9668     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9669     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9670
9671     doctype = (void*)0xdeadbeef;
9672     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9673     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9674     ok(doctype == NULL, "got %p\n", doctype);
9675
9676     IXMLDOMDocument_Release(doc);
9677 }
9678
9679 static void test_get_tagName(void)
9680 {
9681     IXMLDOMDocument *doc;
9682     IXMLDOMElement *elem, *elem2;
9683     HRESULT hr;
9684     BSTR str;
9685
9686     doc = create_document(&IID_IXMLDOMDocument);
9687
9688     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9689     ok(hr == S_OK, "got 0x%08x\n", hr);
9690
9691     hr = IXMLDOMElement_get_tagName(elem, NULL);
9692     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9693
9694     str = NULL;
9695     hr = IXMLDOMElement_get_tagName(elem, &str);
9696     ok(hr == S_OK, "got 0x%08x\n", hr);
9697     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9698     SysFreeString(str);
9699
9700     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9701     ok(hr == S_OK, "got 0x%08x\n", hr);
9702
9703     str = NULL;
9704     hr = IXMLDOMElement_get_tagName(elem2, &str);
9705     ok(hr == S_OK, "got 0x%08x\n", hr);
9706     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9707     SysFreeString(str);
9708
9709     IXMLDOMDocument_Release(elem);
9710     IXMLDOMDocument_Release(elem2);
9711     IXMLDOMDocument_Release(doc);
9712     free_bstrs();
9713 }
9714
9715 typedef struct {
9716     DOMNodeType type;
9717     const char *name;
9718     VARTYPE vt;
9719     HRESULT hr;
9720 } node_type_t;
9721
9722 static const node_type_t get_datatype[] = {
9723     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9724     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9725     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9726     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9727     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9728     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9729     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9730     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9731     { 0 }
9732 };
9733
9734 static void test_get_dataType(void)
9735 {
9736     const node_type_t *entry = get_datatype;
9737     IXMLDOMDocument *doc;
9738
9739     doc = create_document(&IID_IXMLDOMDocument);
9740
9741     while (entry->type)
9742     {
9743         IXMLDOMNode *node = NULL;
9744         VARIANT var, type;
9745         HRESULT hr;
9746
9747         V_VT(&var) = VT_I4;
9748         V_I4(&var) = entry->type;
9749         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9750         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9751
9752         hr = IXMLDOMNode_get_dataType(node, NULL);
9753         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9754
9755         VariantInit(&type);
9756         hr = IXMLDOMNode_get_dataType(node, &type);
9757         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9758             hr, entry->hr, entry->type);
9759         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9760             V_VT(&type), entry->vt, entry->type);
9761         VariantClear(&type);
9762
9763         IXMLDOMNode_Release(node);
9764
9765         entry++;
9766     }
9767
9768     IXMLDOMDocument_Release(doc);
9769     free_bstrs();
9770 }
9771
9772 typedef struct _get_node_typestring_t {
9773     DOMNodeType type;
9774     const char *string;
9775 } get_node_typestring_t;
9776
9777 static const get_node_typestring_t get_node_typestring[] = {
9778     { NODE_ELEMENT,                "element"               },
9779     { NODE_ATTRIBUTE,              "attribute"             },
9780     { NODE_TEXT,                   "text"                  },
9781     { NODE_CDATA_SECTION ,         "cdatasection"          },
9782     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9783     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9784     { NODE_COMMENT,                "comment"               },
9785     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9786     { 0 }
9787 };
9788
9789 static void test_get_nodeTypeString(void)
9790 {
9791     const get_node_typestring_t *entry = get_node_typestring;
9792     IXMLDOMDocument *doc;
9793     HRESULT hr;
9794     BSTR str;
9795
9796     doc = create_document(&IID_IXMLDOMDocument);
9797
9798     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9799     ok(hr == S_OK, "got 0x%08x\n", hr);
9800     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9801     SysFreeString(str);
9802
9803     while (entry->type)
9804     {
9805         IXMLDOMNode *node = NULL;
9806         VARIANT var;
9807
9808         V_VT(&var) = VT_I4;
9809         V_I4(&var) = entry->type;
9810         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9811         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9812
9813         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9814         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9815
9816         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9817         ok(hr == S_OK, "got 0x%08x\n", hr);
9818         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9819             wine_dbgstr_w(str), entry->string, entry->type);
9820         SysFreeString(str);
9821         IXMLDOMNode_Release(node);
9822
9823         entry++;
9824     }
9825
9826     IXMLDOMDocument_Release(doc);
9827     free_bstrs();
9828 }
9829
9830 typedef struct _get_attributes_t {
9831     DOMNodeType type;
9832     HRESULT hr;
9833 } get_attributes_t;
9834
9835 static const get_attributes_t get_attributes[] = {
9836     { NODE_ATTRIBUTE,              S_FALSE },
9837     { NODE_TEXT,                   S_FALSE },
9838     { NODE_CDATA_SECTION ,         S_FALSE },
9839     { NODE_ENTITY_REFERENCE,       S_FALSE },
9840     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9841     { NODE_COMMENT,                S_FALSE },
9842     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9843     { 0 }
9844 };
9845
9846 static void test_get_attributes(void)
9847 {
9848     const get_attributes_t *entry = get_attributes;
9849     IXMLDOMNamedNodeMap *map;
9850     IXMLDOMDocument *doc;
9851     IXMLDOMNode *node, *node2;
9852     VARIANT_BOOL b;
9853     HRESULT hr;
9854     BSTR str;
9855     LONG length;
9856
9857     doc = create_document(&IID_IXMLDOMDocument);
9858
9859     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9860     ok(hr == S_OK, "got %08x\n", hr);
9861
9862     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9863     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9864
9865     map = (void*)0xdeadbeef;
9866     hr = IXMLDOMDocument_get_attributes(doc, &map);
9867     ok(hr == S_FALSE, "got %08x\n", hr);
9868     ok(map == NULL, "got %p\n", map);
9869
9870     /* first child is <?xml ?> */
9871     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9872     ok(hr == S_OK, "got %08x\n", hr);
9873
9874     hr = IXMLDOMNode_get_attributes(node, &map);
9875     ok(hr == S_OK, "got %08x\n", hr);
9876
9877     length = -1;
9878     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9879     EXPECT_HR(hr, S_OK);
9880     todo_wine ok(length == 1, "got %d\n", length);
9881
9882     if (hr == S_OK && length == 1)
9883     {
9884         IXMLDOMAttribute *attr;
9885         DOMNodeType type;
9886         VARIANT v;
9887
9888         node2 = NULL;
9889         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9890         EXPECT_HR(hr, S_OK);
9891         ok(node != NULL, "got %p\n", node2);
9892
9893         hr = IXMLDOMNode_get_nodeName(node2, &str);
9894         EXPECT_HR(hr, S_OK);
9895         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9896         SysFreeString(str);
9897
9898         length = -1;
9899         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9900         EXPECT_HR(hr, S_OK);
9901         ok(length == 1, "got %d\n", length);
9902
9903         type = -1;
9904         hr = IXMLDOMNode_get_nodeType(node2, &type);
9905         EXPECT_HR(hr, S_OK);
9906         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9907
9908         hr = IXMLDOMNode_get_xml(node, &str);
9909         EXPECT_HR(hr, S_OK);
9910         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9911         SysFreeString(str);
9912
9913         hr = IXMLDOMNode_get_text(node, &str);
9914         EXPECT_HR(hr, S_OK);
9915         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9916         SysFreeString(str);
9917
9918         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9919         EXPECT_HR(hr, S_OK);
9920
9921         length = -1;
9922         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9923         EXPECT_HR(hr, S_OK);
9924         ok(length == 0, "got %d\n", length);
9925
9926         hr = IXMLDOMNode_get_xml(node, &str);
9927         EXPECT_HR(hr, S_OK);
9928         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9929         SysFreeString(str);
9930
9931         hr = IXMLDOMNode_get_text(node, &str);
9932         EXPECT_HR(hr, S_OK);
9933         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9934         SysFreeString(str);
9935
9936         IXMLDOMNamedNodeMap_Release(map);
9937
9938         hr = IXMLDOMNode_get_attributes(node, &map);
9939         ok(hr == S_OK, "got %08x\n", hr);
9940
9941         length = -1;
9942         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9943         EXPECT_HR(hr, S_OK);
9944         ok(length == 0, "got %d\n", length);
9945
9946         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9947         EXPECT_HR(hr, S_OK);
9948
9949         V_VT(&v) = VT_BSTR;
9950         V_BSTR(&v) = _bstr_("UTF-8");
9951         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9952         EXPECT_HR(hr, S_OK);
9953
9954         EXPECT_REF(attr, 2);
9955         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9956         EXPECT_HR(hr, S_OK);
9957         EXPECT_REF(attr, 2);
9958
9959         hr = IXMLDOMNode_get_attributes(node, &map);
9960         ok(hr == S_OK, "got %08x\n", hr);
9961
9962         length = -1;
9963         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9964         EXPECT_HR(hr, S_OK);
9965         ok(length == 1, "got %d\n", length);
9966
9967         hr = IXMLDOMNode_get_xml(node, &str);
9968         EXPECT_HR(hr, S_OK);
9969         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9970         SysFreeString(str);
9971
9972         hr = IXMLDOMNode_get_text(node, &str);
9973         EXPECT_HR(hr, S_OK);
9974         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9975         SysFreeString(str);
9976
9977         IXMLDOMNamedNodeMap_Release(map);
9978         IXMLDOMNode_Release(node2);
9979     }
9980
9981     IXMLDOMNode_Release(node);
9982
9983     /* last child is element */
9984     EXPECT_REF(doc, 1);
9985     hr = IXMLDOMDocument_get_lastChild(doc, &node);
9986     ok(hr == S_OK, "got %08x\n", hr);
9987     EXPECT_REF(doc, 1);
9988
9989     EXPECT_REF(node, 1);
9990     hr = IXMLDOMNode_get_attributes(node, &map);
9991     ok(hr == S_OK, "got %08x\n", hr);
9992     EXPECT_REF(node, 1);
9993     EXPECT_REF(doc, 1);
9994
9995     EXPECT_REF(map, 1);
9996     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9997     ok(hr == S_OK, "got %08x\n", hr);
9998     EXPECT_REF(node, 1);
9999     EXPECT_REF(node2, 1);
10000     EXPECT_REF(map, 1);
10001     EXPECT_REF(doc, 1);
10002     IXMLDOMNode_Release(node2);
10003
10004     /* release node before map release, map still works */
10005     IXMLDOMNode_Release(node);
10006
10007     length = 0;
10008     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10009     ok(hr == S_OK, "got %08x\n", hr);
10010     ok(length == 1, "got %d\n", length);
10011
10012     node2 = NULL;
10013     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10014     ok(hr == S_OK, "got %08x\n", hr);
10015     EXPECT_REF(node2, 1);
10016     IXMLDOMNode_Release(node2);
10017
10018     IXMLDOMNamedNodeMap_Release(map);
10019
10020     while (entry->type)
10021     {
10022         VARIANT var;
10023
10024         node = NULL;
10025
10026         V_VT(&var) = VT_I4;
10027         V_I4(&var) = entry->type;
10028         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10029         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10030
10031         hr = IXMLDOMNode_get_attributes(node, NULL);
10032         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10033
10034         map = (void*)0xdeadbeef;
10035         hr = IXMLDOMNode_get_attributes(node, &map);
10036         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10037             hr, entry->hr, entry->type);
10038         ok(map == NULL, "got %p\n", map);
10039
10040         IXMLDOMNode_Release(node);
10041
10042         entry++;
10043     }
10044
10045     IXMLDOMDocument_Release(doc);
10046     free_bstrs();
10047 }
10048
10049 static void test_selection(void)
10050 {
10051     IXMLDOMSelection *selection, *selection2;
10052     IEnumVARIANT *enum1, *enum2, *enum3;
10053     IXMLDOMNodeList *list;
10054     IXMLDOMDocument *doc;
10055     IDispatchEx *dispex;
10056     IXMLDOMNode *node;
10057     IDispatch *disp;
10058     VARIANT_BOOL b;
10059     HRESULT hr;
10060     DISPID did;
10061     VARIANT v;
10062     BSTR name;
10063     ULONG ret;
10064     LONG len;
10065
10066     doc = create_document(&IID_IXMLDOMDocument);
10067
10068     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
10069     EXPECT_HR(hr, S_OK);
10070
10071     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10072     EXPECT_HR(hr, S_OK);
10073
10074     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10075     EXPECT_HR(hr, S_OK);
10076     IXMLDOMSelection_Release(selection);
10077
10078     /* collection disp id */
10079     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10080     EXPECT_HR(hr, S_OK);
10081     did = 0;
10082     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10083     EXPECT_HR(hr, S_OK);
10084     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10085     len = 0;
10086     hr = IXMLDOMSelection_get_length(selection, &len);
10087     EXPECT_HR(hr, S_OK);
10088     ok(len == 1, "got %d\n", len);
10089     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10090     EXPECT_HR(hr, S_OK);
10091     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10092     IDispatchEx_Release(dispex);
10093
10094     /* IEnumVARIANT tests */
10095     enum1 = NULL;
10096     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10097     EXPECT_HR(hr, S_OK);
10098     ok(enum1 != NULL, "got %p\n", enum1);
10099     EXPECT_REF(enum1, 2);
10100
10101     enum3 = NULL;
10102     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10103     EXPECT_HR(hr, S_OK);
10104     ok(enum3 != NULL, "got %p\n", enum3);
10105     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10106     EXPECT_REF(enum1, 3);
10107     IEnumVARIANT_Release(enum3);
10108
10109     EXPECT_REF(selection, 1);
10110     EXPECT_REF(enum1, 2);
10111
10112     enum2 = NULL;
10113     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10114     EXPECT_HR(hr, S_OK);
10115     ok(enum2 != NULL, "got %p\n", enum2);
10116
10117     EXPECT_REF(selection, 2);
10118     EXPECT_REF(enum1, 2);
10119     EXPECT_REF(enum2, 1);
10120
10121     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10122
10123     selection2 = NULL;
10124     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10125     EXPECT_HR(hr, S_OK);
10126     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10127     EXPECT_REF(selection, 3);
10128     EXPECT_REF(enum1, 2);
10129
10130     IXMLDOMSelection_Release(selection2);
10131
10132     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10133     EXPECT_HR(hr, S_OK);
10134     EXPECT_REF(selection, 3);
10135     IDispatch_Release(disp);
10136
10137     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10138     EXPECT_HR(hr, S_OK);
10139     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10140     EXPECT_REF(selection, 2);
10141     EXPECT_REF(enum1, 3);
10142
10143     IEnumVARIANT_Release(enum1);
10144     IEnumVARIANT_Release(enum2);
10145
10146     enum1 = NULL;
10147     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10148     EXPECT_HR(hr, S_OK);
10149     ok(enum1 != NULL, "got %p\n", enum1);
10150     EXPECT_REF(enum1, 1);
10151     EXPECT_REF(selection, 2);
10152
10153     enum2 = NULL;
10154     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10155     EXPECT_HR(hr, S_OK);
10156     ok(enum2 != NULL, "got %p\n", enum2);
10157     EXPECT_REF(enum2, 1);
10158     EXPECT_REF(selection, 3);
10159
10160     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10161
10162     IEnumVARIANT_AddRef(enum1);
10163     EXPECT_REF(selection, 3);
10164     EXPECT_REF(enum1, 2);
10165     EXPECT_REF(enum2, 1);
10166     IEnumVARIANT_Release(enum1);
10167
10168     IEnumVARIANT_Release(enum1);
10169     IEnumVARIANT_Release(enum2);
10170
10171     EXPECT_REF(selection, 1);
10172
10173     IXMLDOMNodeList_Release(list);
10174
10175     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10176     EXPECT_HR(hr, S_OK);
10177
10178     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10179     EXPECT_HR(hr, E_NOINTERFACE);
10180
10181     IXMLDOMNodeList_Release(list);
10182
10183     /* test if IEnumVARIANT touches selection context */
10184     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10185     EXPECT_HR(hr, S_OK);
10186
10187     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10188     EXPECT_HR(hr, S_OK);
10189
10190     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10191     EXPECT_HR(hr, S_OK);
10192
10193     len = 0;
10194     hr = IXMLDOMSelection_get_length(selection, &len);
10195     EXPECT_HR(hr, S_OK);
10196     ok(len == 4, "got %d\n", len);
10197
10198     enum1 = NULL;
10199     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10200     EXPECT_HR(hr, S_OK);
10201
10202     /* no-op if zero count */
10203     V_VT(&v) = VT_I2;
10204     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10205     EXPECT_HR(hr, S_OK);
10206     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10207
10208     /* positive count, null array pointer */
10209     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10210     EXPECT_HR(hr, E_INVALIDARG);
10211
10212     ret = 1;
10213     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10214     EXPECT_HR(hr, E_INVALIDARG);
10215     ok(ret == 0, "got %d\n", ret);
10216
10217     V_VT(&v) = VT_I2;
10218     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10219     EXPECT_HR(hr, S_OK);
10220     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10221
10222     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10223     EXPECT_HR(hr, S_OK);
10224     hr = IXMLDOMNode_get_nodeName(node, &name);
10225     EXPECT_HR(hr, S_OK);
10226     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10227     SysFreeString(name);
10228     IXMLDOMNode_Release(node);
10229     VariantClear(&v);
10230
10231     /* list cursor is updated */
10232     hr = IXMLDOMSelection_nextNode(selection, &node);
10233     EXPECT_HR(hr, S_OK);
10234     hr = IXMLDOMNode_get_nodeName(node, &name);
10235     EXPECT_HR(hr, S_OK);
10236     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10237     IXMLDOMNode_Release(node);
10238
10239     V_VT(&v) = VT_I2;
10240     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10241     EXPECT_HR(hr, S_OK);
10242     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10243     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10244     EXPECT_HR(hr, S_OK);
10245     hr = IXMLDOMNode_get_nodeName(node, &name);
10246     EXPECT_HR(hr, S_OK);
10247     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10248     SysFreeString(name);
10249     IXMLDOMNode_Release(node);
10250     VariantClear(&v);
10251
10252     hr = IXMLDOMSelection_nextNode(selection, &node);
10253     EXPECT_HR(hr, S_OK);
10254     hr = IXMLDOMNode_get_nodeName(node, &name);
10255     EXPECT_HR(hr, S_OK);
10256     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10257     IXMLDOMNode_Release(node);
10258
10259     IXMLDOMSelection_Release(selection);
10260     IXMLDOMNodeList_Release(list);
10261     IXMLDOMDocument_Release(doc);
10262
10263     free_bstrs();
10264 }
10265
10266 static void test_load(void)
10267 {
10268     IXMLDOMDocument *doc;
10269     IXMLDOMNodeList *list;
10270     VARIANT_BOOL b;
10271     HANDLE hfile;
10272     VARIANT src;
10273     HRESULT hr;
10274     BOOL ret;
10275     BSTR path, bstr1, bstr2;
10276     DWORD written;
10277     void* ptr;
10278
10279     /* prepare a file */
10280     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10281     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10282     if(hfile == INVALID_HANDLE_VALUE) return;
10283
10284     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10285     ok(ret, "WriteFile failed\n");
10286
10287     CloseHandle(hfile);
10288
10289     doc = create_document(&IID_IXMLDOMDocument);
10290
10291     path = _bstr_("test.xml");
10292
10293     /* load from path: VT_BSTR */
10294     V_VT(&src) = VT_BSTR;
10295     V_BSTR(&src) = path;
10296     hr = IXMLDOMDocument_load(doc, src, &b);
10297     EXPECT_HR(hr, S_OK);
10298     ok(b == VARIANT_TRUE, "got %d\n", b);
10299
10300     /* load from a path: VT_BSTR|VT_BYREF */
10301     V_VT(&src) = VT_BSTR | VT_BYREF;
10302     V_BSTRREF(&src) = &path;
10303     hr = IXMLDOMDocument_load(doc, src, &b);
10304     EXPECT_HR(hr, S_OK);
10305     ok(b == VARIANT_TRUE, "got %d\n", b);
10306
10307     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10308     V_VT(&src) = VT_BSTR | VT_BYREF;
10309     V_BSTRREF(&src) = NULL;
10310     hr = IXMLDOMDocument_load(doc, src, &b);
10311     EXPECT_HR(hr, E_INVALIDARG);
10312     ok(b == VARIANT_FALSE, "got %d\n", b);
10313
10314     IXMLDOMDocument_Release(doc);
10315
10316     DeleteFileA("test.xml");
10317
10318     doc = create_document(&IID_IXMLDOMDocument);
10319
10320     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10321     EXPECT_HR(hr, S_OK);
10322     ok(b == VARIANT_TRUE, "got %d\n", b);
10323
10324     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10325     EXPECT_HR(hr, S_OK);
10326     bstr1 = _bstr_(list_to_string(list));
10327
10328     hr = IXMLDOMNodeList_reset(list);
10329     EXPECT_HR(hr, S_OK);
10330
10331     IXMLDOMDocument_Release(doc);
10332
10333     doc = create_document(&IID_IXMLDOMDocument);
10334
10335     VariantInit(&src);
10336     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10337     V_VT(&src) = VT_ARRAY|VT_UI1;
10338     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10339     ptr = NULL;
10340     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10341     EXPECT_HR(hr, S_OK);
10342     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10343
10344     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10345     hr = SafeArrayUnlock(V_ARRAY(&src));
10346     EXPECT_HR(hr, S_OK);
10347
10348     hr = IXMLDOMDocument_load(doc, src, &b);
10349     EXPECT_HR(hr, S_OK);
10350     ok(b == VARIANT_TRUE, "got %d\n", b);
10351
10352     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10353     EXPECT_HR(hr, S_OK);
10354     bstr2 = _bstr_(list_to_string(list));
10355
10356     hr = IXMLDOMNodeList_reset(list);
10357     EXPECT_HR(hr, S_OK);
10358
10359     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10360        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10361
10362     IXMLDOMDocument_Release(doc);
10363     IXMLDOMNodeList_Release(list);
10364     VariantClear(&src);
10365
10366     /* UTF-16 isn't accepted */
10367     doc = create_document(&IID_IXMLDOMDocument);
10368
10369     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10370     V_VT(&src) = VT_ARRAY|VT_UI1;
10371     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10372     ptr = NULL;
10373     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10374     EXPECT_HR(hr, S_OK);
10375     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10376
10377     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10378     hr = SafeArrayUnlock(V_ARRAY(&src));
10379     EXPECT_HR(hr, S_OK);
10380
10381     hr = IXMLDOMDocument_load(doc, src, &b);
10382     todo_wine EXPECT_HR(hr, S_FALSE);
10383     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10384
10385     VariantClear(&src);
10386
10387     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10388     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10389     V_VT(&src) = VT_ARRAY|VT_UI2;
10390     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10391     ptr = NULL;
10392     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10393     EXPECT_HR(hr, S_OK);
10394     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10395
10396     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10397     hr = SafeArrayUnlock(V_ARRAY(&src));
10398     EXPECT_HR(hr, S_OK);
10399
10400     hr = IXMLDOMDocument_load(doc, src, &b);
10401     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10402     ok(b == VARIANT_FALSE, "got %d\n", b);
10403
10404     VariantClear(&src);
10405     IXMLDOMDocument_Release(doc);
10406
10407     free_bstrs();
10408 }
10409
10410 static void test_domobj_dispex(IUnknown *obj)
10411 {
10412     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10413     IDispatchEx *dispex;
10414     IUnknown *unk;
10415     DWORD props;
10416     UINT ticnt;
10417     HRESULT hr;
10418     BSTR name;
10419
10420     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10421     EXPECT_HR(hr, S_OK);
10422     if (FAILED(hr)) return;
10423
10424     ticnt = 0;
10425     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10426     EXPECT_HR(hr, S_OK);
10427     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10428
10429     name = SysAllocString(szstar);
10430     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10431     EXPECT_HR(hr, E_NOTIMPL);
10432     SysFreeString(name);
10433
10434     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10435     EXPECT_HR(hr, E_NOTIMPL);
10436
10437     props = 0;
10438     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10439     EXPECT_HR(hr, E_NOTIMPL);
10440     ok(props == 0, "expected 0 got %d\n", props);
10441
10442     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10443     EXPECT_HR(hr, E_NOTIMPL);
10444     if (SUCCEEDED(hr)) SysFreeString(name);
10445
10446     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10447     EXPECT_HR(hr, E_NOTIMPL);
10448
10449     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10450     EXPECT_HR(hr, E_NOTIMPL);
10451     if (hr == S_OK && unk) IUnknown_Release(unk);
10452
10453     IDispatchEx_Release(dispex);
10454 }
10455
10456 static void test_nsnamespacemanager(void)
10457 {
10458     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10459     IVBMXNamespaceManager *mgr2;
10460     IMXNamespaceManager *nsmgr;
10461     WCHAR buffW[250];
10462     IDispatch *disp;
10463     IUnknown *unk;
10464     HRESULT hr;
10465     INT len;
10466
10467     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10468         &IID_IMXNamespaceManager, (void**)&nsmgr);
10469     EXPECT_HR(hr, S_OK);
10470
10471     /* IMXNamespaceManager inherits from IUnknown */
10472     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10473     EXPECT_HR(hr, S_OK);
10474     IDispatch_Release(disp);
10475
10476     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10477     EXPECT_HR(hr, S_OK);
10478     IVBMXNamespaceManager_Release(mgr2);
10479
10480     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10481     EXPECT_HR(hr, S_OK);
10482
10483     /* prefix already added */
10484     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10485     EXPECT_HR(hr, S_FALSE);
10486
10487     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10488     EXPECT_HR(hr, E_INVALIDARG);
10489
10490     /* "xml" and "xmlns" are not allowed here */
10491     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10492     EXPECT_HR(hr, E_INVALIDARG);
10493
10494     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10495     EXPECT_HR(hr, E_INVALIDARG);
10496 todo_wine {
10497     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10498     EXPECT_HR(hr, E_FAIL);
10499 }
10500     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10501     EXPECT_HR(hr, E_POINTER);
10502
10503     len = -1;
10504     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10505     EXPECT_HR(hr, S_OK);
10506     ok(len == 3, "got %d\n", len);
10507
10508     len = -1;
10509     buffW[0] = 0x1;
10510     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10511     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10512     ok(len == -1, "got %d\n", len);
10513     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10514
10515     len = 10;
10516     buffW[0] = 0x1;
10517     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10518     EXPECT_HR(hr, S_OK);
10519     ok(len == 3, "got %d\n", len);
10520     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10521
10522     /* getURI */
10523     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10524     EXPECT_HR(hr, E_INVALIDARG);
10525
10526     len = -1;
10527     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10528     EXPECT_HR(hr, E_INVALIDARG);
10529     ok(len == -1, "got %d\n", len);
10530
10531     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10532     EXPECT_HR(hr, E_POINTER);
10533
10534     len = -1;
10535     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10536     EXPECT_HR(hr, S_OK);
10537     /* length of "xml" uri is constant */
10538     ok(len == strlen(xmluriA), "got %d\n", len);
10539
10540     len = 100;
10541     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10542     EXPECT_HR(hr, S_OK);
10543     ok(len == strlen(xmluriA), "got %d\n", len);
10544     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10545
10546     len = strlen(xmluriA)-1;
10547     buffW[0] = 0x1;
10548     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10549     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10550     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10551     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10552
10553     /* prefix xml1 not defined */
10554     len = -1;
10555     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10556     EXPECT_HR(hr, S_FALSE);
10557     ok(len == 0, "got %d\n", len);
10558
10559     len = 100;
10560     buffW[0] = 0x1;
10561     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10562     EXPECT_HR(hr, S_FALSE);
10563     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10564     ok(len == 0, "got %d\n", len);
10565
10566     /* IDispatchEx tests */
10567     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10568     EXPECT_HR(hr, S_OK);
10569     test_domobj_dispex(unk);
10570     IUnknown_Release(unk);
10571
10572     IMXNamespaceManager_Release(nsmgr);
10573
10574     free_bstrs();
10575 }
10576
10577 static void test_nsnamespacemanager_override(void)
10578 {
10579     IMXNamespaceManager *nsmgr;
10580     WCHAR buffW[250];
10581     VARIANT_BOOL b;
10582     HRESULT hr;
10583     INT len;
10584
10585     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10586         &IID_IMXNamespaceManager, (void**)&nsmgr);
10587     EXPECT_HR(hr, S_OK);
10588
10589     len = sizeof(buffW)/sizeof(WCHAR);
10590     buffW[0] = 0;
10591     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10592     EXPECT_HR(hr, S_OK);
10593     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10594
10595     len = sizeof(buffW)/sizeof(WCHAR);
10596     buffW[0] = 0;
10597     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10598     EXPECT_HR(hr, E_FAIL);
10599
10600     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10601     EXPECT_HR(hr, E_POINTER);
10602
10603     b = VARIANT_FALSE;
10604     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10605     EXPECT_HR(hr, S_OK);
10606     ok(b == VARIANT_TRUE, "got %d\n", b);
10607
10608     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10609     EXPECT_HR(hr, S_OK);
10610
10611     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10612     EXPECT_HR(hr, S_OK);
10613
10614     len = sizeof(buffW)/sizeof(WCHAR);
10615     buffW[0] = 0;
10616     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10617     EXPECT_HR(hr, S_OK);
10618     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10619
10620     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10621     EXPECT_HR(hr, S_OK);
10622
10623     len = sizeof(buffW)/sizeof(WCHAR);
10624     buffW[0] = 0;
10625     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10626     EXPECT_HR(hr, S_OK);
10627     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10628
10629     len = sizeof(buffW)/sizeof(WCHAR);
10630     buffW[0] = 0;
10631     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10632     EXPECT_HR(hr, S_OK);
10633     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10634
10635     len = sizeof(buffW)/sizeof(WCHAR);
10636     buffW[0] = 0;
10637     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10638     EXPECT_HR(hr, S_OK);
10639     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10640
10641     /* new prefix placed at index 1 always */
10642     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10643     EXPECT_HR(hr, S_OK);
10644
10645     len = sizeof(buffW)/sizeof(WCHAR);
10646     buffW[0] = 0;
10647     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10648     EXPECT_HR(hr, S_OK);
10649     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10650
10651     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10652     todo_wine EXPECT_HR(hr, E_FAIL);
10653
10654     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10655     EXPECT_HR(hr, E_FAIL);
10656
10657     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10658     EXPECT_HR(hr, E_FAIL);
10659
10660     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10661     EXPECT_HR(hr, S_OK);
10662
10663     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10664     EXPECT_HR(hr, S_FALSE);
10665
10666     len = sizeof(buffW)/sizeof(WCHAR);
10667     buffW[0] = 0;
10668     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10669     EXPECT_HR(hr, S_OK);
10670     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10671
10672     len = sizeof(buffW)/sizeof(WCHAR);
10673     buffW[0] = 0;
10674     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10675     EXPECT_HR(hr, S_OK);
10676     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10677
10678     IMXNamespaceManager_Release(nsmgr);
10679
10680     free_bstrs();
10681 }
10682
10683 static const DOMNodeType nodetypes_test[] =
10684 {
10685     NODE_ELEMENT,
10686     NODE_ATTRIBUTE,
10687     NODE_TEXT,
10688     NODE_CDATA_SECTION,
10689     NODE_ENTITY_REFERENCE,
10690     NODE_PROCESSING_INSTRUCTION,
10691     NODE_COMMENT,
10692     NODE_DOCUMENT_FRAGMENT,
10693     NODE_INVALID
10694 };
10695
10696 static void test_dispex(void)
10697 {
10698     const DOMNodeType *type = nodetypes_test;
10699     IXMLDOMImplementation *impl;
10700     IXMLDOMNodeList *node_list;
10701     IXMLDOMParseError *error;
10702     IXMLDOMNamedNodeMap *map;
10703     IXSLProcessor *processor;
10704     IXSLTemplate *template;
10705     IXMLDOMDocument *doc;
10706     IXMLHTTPRequest *req;
10707     IXMLDOMElement *elem;
10708     IDispatchEx *dispex;
10709     IXMLDOMNode *node;
10710     VARIANT_BOOL b;
10711     IUnknown *unk;
10712     HRESULT hr;
10713     DISPID did;
10714
10715     doc = create_document(&IID_IXMLDOMDocument);
10716
10717     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10718     test_domobj_dispex(unk);
10719     IUnknown_Release(unk);
10720
10721     for(; *type != NODE_INVALID; type++)
10722     {
10723         IXMLDOMNode *node;
10724         VARIANT v;
10725
10726         V_VT(&v) = VT_I2;
10727         V_I2(&v) = *type;
10728
10729         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10730         ok(hr == S_OK, "failed to create node type %d\n", *type);
10731
10732         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10733
10734         test_domobj_dispex(unk);
10735         IUnknown_Release(unk);
10736         IXMLDOMNode_Release(node);
10737     }
10738
10739     /* IXMLDOMNodeList */
10740     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10741     EXPECT_HR(hr, S_OK);
10742     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10743     test_domobj_dispex(unk);
10744     IUnknown_Release(unk);
10745     IXMLDOMNodeList_Release(node_list);
10746
10747     /* IXMLDOMNodeList for children list */
10748     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10749     EXPECT_HR(hr, S_OK);
10750     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10751     test_domobj_dispex(unk);
10752     IUnknown_Release(unk);
10753
10754     /* collection dispex test, empty collection */
10755     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10756     EXPECT_HR(hr, S_OK);
10757     did = 0;
10758     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10759     EXPECT_HR(hr, S_OK);
10760     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10761     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10762     EXPECT_HR(hr, S_OK);
10763     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10764     IDispatchEx_Release(dispex);
10765
10766     IXMLDOMNodeList_Release(node_list);
10767
10768     /* IXMLDOMParseError */
10769     hr = IXMLDOMDocument_get_parseError(doc, &error);
10770     EXPECT_HR(hr, S_OK);
10771     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
10772     test_domobj_dispex(unk);
10773     IUnknown_Release(unk);
10774     IXMLDOMParseError_Release(error);
10775
10776     /* IXMLDOMNamedNodeMap */
10777     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10778     EXPECT_HR(hr, S_OK);
10779
10780     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
10781     EXPECT_HR(hr, S_OK);
10782     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10783     EXPECT_HR(hr, S_OK);
10784     IXMLDOMNodeList_Release(node_list);
10785
10786     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10787     EXPECT_HR(hr, S_OK);
10788     IXMLDOMNode_Release(node);
10789     hr = IXMLDOMElement_get_attributes(elem, &map);
10790     EXPECT_HR(hr, S_OK);
10791     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
10792     test_domobj_dispex(unk);
10793     IUnknown_Release(unk);
10794     /* collection dispex test */
10795     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10796     EXPECT_HR(hr, S_OK);
10797     did = 0;
10798     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10799     EXPECT_HR(hr, S_OK);
10800     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10801     IDispatchEx_Release(dispex);
10802
10803     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
10804     EXPECT_HR(hr, S_OK);
10805     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10806     EXPECT_HR(hr, S_OK);
10807     IXMLDOMNodeList_Release(node_list);
10808     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10809     EXPECT_HR(hr, S_OK);
10810     IXMLDOMNode_Release(node);
10811     hr = IXMLDOMElement_get_attributes(elem, &map);
10812     EXPECT_HR(hr, S_OK);
10813     /* collection dispex test, empty collection */
10814     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10815     EXPECT_HR(hr, S_OK);
10816     did = 0;
10817     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10818     EXPECT_HR(hr, S_OK);
10819     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10820     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10821     EXPECT_HR(hr, S_OK);
10822     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10823     IDispatchEx_Release(dispex);
10824
10825     IXMLDOMNamedNodeMap_Release(map);
10826     IXMLDOMElement_Release(elem);
10827
10828     /* IXMLDOMImplementation */
10829     hr = IXMLDOMDocument_get_implementation(doc, &impl);
10830     EXPECT_HR(hr, S_OK);
10831
10832     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
10833     EXPECT_HR(hr, S_OK);
10834     IDispatchEx_Release(dispex);
10835     IXMLDOMImplementation_Release(impl);
10836
10837     IXMLDOMDocument_Release(doc);
10838
10839     /* IXMLHTTPRequest */
10840     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
10841         &IID_IXMLHttpRequest, (void**)&req);
10842     if (hr == S_OK)
10843     {
10844         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
10845         EXPECT_HR(hr, E_NOINTERFACE);
10846         IXMLHTTPRequest_Release(req);
10847     }
10848
10849     /* IXSLTemplate */
10850     template = create_xsltemplate(&IID_IXSLTemplate);
10851     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
10852     EXPECT_HR(hr, S_OK);
10853     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
10854     EXPECT_HR(hr, S_OK);
10855     test_domobj_dispex(unk);
10856     IUnknown_Release(unk);
10857     IDispatchEx_Release(dispex);
10858
10859     /* IXSLProcessor */
10860     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
10861     EXPECT_HR(hr, S_OK);
10862     b = VARIANT_FALSE;
10863     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
10864     EXPECT_HR(hr, S_OK);
10865     ok(b == VARIANT_TRUE, "got %d\n", b);
10866
10867     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
10868     EXPECT_HR(hr, S_OK);
10869     IXMLDOMDocument_Release(doc);
10870
10871     hr = IXSLTemplate_createProcessor(template, &processor);
10872     EXPECT_HR(hr, S_OK);
10873     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
10874     EXPECT_HR(hr, S_OK);
10875     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
10876     EXPECT_HR(hr, S_OK);
10877     test_domobj_dispex(unk);
10878     IUnknown_Release(unk);
10879     IDispatchEx_Release(dispex);
10880
10881     IXSLProcessor_Release(processor);
10882     IXSLTemplate_Release(template);
10883
10884     free_bstrs();
10885 }
10886
10887 static void test_parseerror(void)
10888 {
10889     IXMLDOMParseError *error;
10890     IXMLDOMDocument *doc;
10891     HRESULT hr;
10892
10893     doc = create_document(&IID_IXMLDOMDocument);
10894
10895     hr = IXMLDOMDocument_get_parseError(doc, &error);
10896     EXPECT_HR(hr, S_OK);
10897
10898     hr = IXMLDOMParseError_get_line(error, NULL);
10899     EXPECT_HR(hr, E_INVALIDARG);
10900
10901     hr = IXMLDOMParseError_get_srcText(error, NULL);
10902     EXPECT_HR(hr, E_INVALIDARG);
10903
10904     hr = IXMLDOMParseError_get_linepos(error, NULL);
10905     EXPECT_HR(hr, E_INVALIDARG);
10906
10907     IXMLDOMParseError_Release(error);
10908
10909     IXMLDOMDocument_Release(doc);
10910 }
10911
10912 static void test_getAttributeNode(void)
10913 {
10914     IXMLDOMAttribute *attr;
10915     IXMLDOMDocument *doc;
10916     IXMLDOMElement *elem;
10917     VARIANT_BOOL v;
10918     HRESULT hr;
10919     BSTR str;
10920
10921     doc = create_document(&IID_IXMLDOMDocument);
10922
10923     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
10924     EXPECT_HR(hr, S_OK);
10925
10926     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
10927     EXPECT_HR(hr, S_OK);
10928
10929     str = SysAllocString(nonexistent_fileW);
10930     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
10931     EXPECT_HR(hr, E_FAIL);
10932
10933     attr = (IXMLDOMAttribute*)0xdeadbeef;
10934     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
10935     EXPECT_HR(hr, E_FAIL);
10936     ok(attr == NULL, "got %p\n", attr);
10937     SysFreeString(str);
10938
10939     str = SysAllocString(nonexistent_attrW);
10940     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
10941     EXPECT_HR(hr, S_FALSE);
10942
10943     attr = (IXMLDOMAttribute*)0xdeadbeef;
10944     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
10945     EXPECT_HR(hr, S_FALSE);
10946     ok(attr == NULL, "got %p\n", attr);
10947     SysFreeString(str);
10948
10949     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
10950     EXPECT_HR(hr, S_OK);
10951     IXMLDOMAttribute_Release(attr);
10952
10953     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
10954     EXPECT_HR(hr, S_FALSE);
10955
10956     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
10957     EXPECT_HR(hr, S_OK);
10958     IXMLDOMAttribute_Release(attr);
10959
10960     IXMLDOMElement_Release(elem);
10961     IXMLDOMDocument_Release(doc);
10962     free_bstrs();
10963 }
10964
10965 typedef struct {
10966     DOMNodeType type;
10967     const char *name;
10968     REFIID iids[3];
10969 } supporterror_t;
10970
10971 static const supporterror_t supporterror_test[] = {
10972     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
10973     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
10974     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
10975     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
10976     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
10977     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
10978     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
10979     { NODE_INVALID }
10980 };
10981
10982 static void test_supporterrorinfo(void)
10983 {
10984     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
10985                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
10986     const supporterror_t *ptr = supporterror_test;
10987     ISupportErrorInfo *errorinfo, *info2;
10988     IXMLDOMNamedNodeMap *map, *map2;
10989     IXMLDOMDocument *doc;
10990     IXMLDOMElement *elem;
10991     VARIANT_BOOL b;
10992     IUnknown *unk;
10993     REFIID *iid;
10994     void *dummy;
10995     HRESULT hr;
10996
10997     doc = create_document_version(60, &IID_IXMLDOMDocument3);
10998     if (!doc) return;
10999
11000     EXPECT_REF(doc, 1);
11001     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11002     EXPECT_HR(hr, S_OK);
11003     EXPECT_REF(doc, 1);
11004     ISupportErrorInfo_AddRef(errorinfo);
11005     EXPECT_REF(errorinfo, 2);
11006     EXPECT_REF(doc, 1);
11007     ISupportErrorInfo_Release(errorinfo);
11008
11009     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11010     EXPECT_HR(hr, S_OK);
11011     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11012
11013     /* error interface can't be queried back for DOM interface */
11014     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11015     EXPECT_HR(hr, E_NOINTERFACE);
11016     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11017     EXPECT_HR(hr, E_NOINTERFACE);
11018
11019     ISupportErrorInfo_Release(info2);
11020
11021     iid = iids;
11022     while (*iid)
11023     {
11024         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11025         EXPECT_HR(hr, S_OK);
11026         if (hr == S_OK)
11027         {
11028             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11029             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11030             IUnknown_Release(unk);
11031         }
11032
11033         iid++;
11034     }
11035
11036     ISupportErrorInfo_Release(errorinfo);
11037
11038     while (ptr->type != NODE_INVALID)
11039     {
11040         IXMLDOMNode *node;
11041         VARIANT type;
11042
11043         V_VT(&type) = VT_I1;
11044         V_I1(&type) = ptr->type;
11045
11046         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11047         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11048
11049         EXPECT_REF(node, 1);
11050         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11051         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11052         EXPECT_REF(node, 1);
11053
11054         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11055         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11056
11057         iid = ptr->iids;
11058
11059         while (*iid)
11060         {
11061             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11062             if (hr == S_OK)
11063             {
11064                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11065                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11066                 IUnknown_Release(unk);
11067             }
11068
11069             iid++;
11070         }
11071
11072         ISupportErrorInfo_Release(errorinfo);
11073         IXMLDOMNode_Release(node);
11074         ptr++;
11075     }
11076
11077     /* IXMLDOMNamedNodeMap */
11078     b = VARIANT_FALSE;
11079     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11080     EXPECT_HR(hr, S_OK);
11081     ok(b == VARIANT_TRUE, "got %d\n", b);
11082
11083     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11084     EXPECT_HR(hr, S_OK);
11085
11086     hr = IXMLDOMElement_get_attributes(elem, &map);
11087     EXPECT_HR(hr, S_OK);
11088
11089     EXPECT_REF(map, 1);
11090     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11091     EXPECT_HR(hr, S_OK);
11092     EXPECT_REF(map, 2);
11093
11094     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11095     EXPECT_HR(hr, S_OK);
11096
11097     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11098     EXPECT_HR(hr, S_OK);
11099     ok(map == map2, "got %p\n", map2);
11100     IXMLDOMNamedNodeMap_Release(map2);
11101
11102     EXPECT_REF(errorinfo, 2);
11103     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11104     EXPECT_HR(hr, S_OK);
11105     EXPECT_REF(errorinfo, 3);
11106     EXPECT_REF(map, 3);
11107     IUnknown_Release(unk);
11108
11109     ISupportErrorInfo_Release(errorinfo);
11110     IXMLDOMNamedNodeMap_Release(map);
11111     IXMLDOMElement_Release(elem);
11112
11113     IXMLDOMDocument_Release(doc);
11114     free_bstrs();
11115 }
11116
11117 typedef struct {
11118     DOMNodeType type;
11119     const char *name;
11120     const char *put_content;
11121     HRESULT put_hr;
11122     VARTYPE get_vt;
11123     HRESULT get_hr;
11124 } node_value_t;
11125
11126 static const node_value_t nodevalue_test[] = {
11127     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11128     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11129     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11130     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11131     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11132     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11133     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11134     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11135     { NODE_INVALID }
11136 };
11137
11138 static void test_nodeValue(void)
11139 {
11140     const node_value_t *ptr = nodevalue_test;
11141     IXMLDOMDocument *doc;
11142     HRESULT hr;
11143
11144     doc = create_document(&IID_IXMLDOMDocument);
11145     if (!doc) return;
11146
11147     while (ptr->type != NODE_INVALID)
11148     {
11149         IXMLDOMNode *node;
11150         VARIANT v;
11151
11152         V_VT(&v) = VT_I2;
11153         V_I2(&v) = ptr->type;
11154
11155         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11156         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11157
11158         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11159         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11160
11161         V_VT(&v) = VT_BSTR;
11162         V_BSTR(&v) = _bstr_(ptr->put_content);
11163         hr = IXMLDOMNode_put_nodeValue(node, v);
11164         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11165
11166         V_VT(&v) = VT_EMPTY;
11167         hr = IXMLDOMNode_get_nodeValue(node, &v);
11168         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11169         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11170         if (hr == S_OK)
11171             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11172                 wine_dbgstr_w(V_BSTR(&v)));
11173         VariantClear(&v);
11174
11175         IXMLDOMNode_Release(node);
11176
11177         ptr++;
11178     }
11179
11180     IXMLDOMDocument_Release(doc);
11181 }
11182
11183 START_TEST(domdoc)
11184 {
11185     IXMLDOMDocument *doc;
11186     IUnknown *unk;
11187     HRESULT hr;
11188
11189     hr = CoInitialize( NULL );
11190     ok( hr == S_OK, "failed to init com\n");
11191     if (hr != S_OK) return;
11192
11193     test_XMLHTTP();
11194
11195     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
11196     if (hr != S_OK)
11197     {
11198         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
11199         return;
11200     }
11201
11202     IXMLDOMDocument_Release(doc);
11203
11204     test_domdoc();
11205     test_persiststreaminit();
11206     test_domnode();
11207     test_refs();
11208     test_create();
11209     test_getElementsByTagName();
11210     test_get_text();
11211     test_get_childNodes();
11212     test_get_firstChild();
11213     test_get_lastChild();
11214     test_removeChild();
11215     test_replaceChild();
11216     test_removeNamedItem();
11217     test_IXMLDOMDocument2();
11218     test_whitespace();
11219     test_XPath();
11220     test_XSLPattern();
11221     test_cloneNode();
11222     test_xmlTypes();
11223     test_nodeTypeTests();
11224     test_save();
11225     test_testTransforms();
11226     test_namespaces();
11227     test_FormattingXML();
11228     test_nodeTypedValue();
11229     test_TransformWithLoadingLocalFile();
11230     test_put_nodeValue();
11231     test_document_IObjectSafety();
11232     test_splitText();
11233     test_getQualifiedItem();
11234     test_removeQualifiedItem();
11235     test_get_ownerDocument();
11236     test_setAttributeNode();
11237     test_put_dataType();
11238     test_createNode();
11239     test_get_prefix();
11240     test_default_properties();
11241     test_selectSingleNode();
11242     test_events();
11243     test_createProcessingInstruction();
11244     test_put_nodeTypedValue();
11245     test_get_xml();
11246     test_insertBefore();
11247     test_appendChild();
11248     test_get_doctype();
11249     test_get_tagName();
11250     test_get_dataType();
11251     test_get_nodeTypeString();
11252     test_get_attributes();
11253     test_selection();
11254     test_load();
11255     test_dispex();
11256     test_parseerror();
11257     test_getAttributeNode();
11258     test_supporterrorinfo();
11259     test_nodeValue();
11260
11261     test_xsltemplate();
11262
11263     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11264         &IID_IMXNamespaceManager, (void**)&unk);
11265     if (hr == S_OK)
11266     {
11267         test_nsnamespacemanager();
11268         test_nsnamespacemanager_override();
11269
11270         IUnknown_Release(unk);
11271     }
11272     else
11273         win_skip("MXNamespaceManager is not available\n");
11274
11275     CoUninitialize();
11276 }