msxml3/tests: Check the correct return value.
[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-2012 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 /* undef the #define in msxml2 so that we can access all versions */
45 #undef CLSID_DOMDocument
46
47 DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
48 DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
49 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
50
51 #define DEFINE_EXPECT(func) \
52     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
53
54 #define SET_EXPECT(func) \
55     expect_ ## func = TRUE
56
57 #define CHECK_EXPECT2(func) \
58     do { \
59         ok(expect_ ##func, "unexpected call " #func "\n"); \
60         called_ ## func = TRUE; \
61     }while(0)
62
63 #define CHECK_CALLED(func) \
64     do { \
65         ok(called_ ## func, "expected " #func "\n"); \
66         expect_ ## func = called_ ## func = FALSE; \
67     }while(0)
68
69 static const char *debugstr_guid(REFIID riid)
70 {
71     static char buf[50];
72
73     if(!riid)
74         return "(null)";
75
76     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
77             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
78             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
79             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
80
81     return buf;
82 }
83
84 static int g_unexpectedcall, g_expectedcall;
85
86 typedef struct
87 {
88     IDispatch IDispatch_iface;
89     LONG ref;
90 } dispevent;
91
92 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
93 {
94     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
95 }
96
97 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
98 {
99     *ppvObject = NULL;
100
101     if ( IsEqualGUID( riid, &IID_IDispatch) ||
102          IsEqualGUID( riid, &IID_IUnknown) )
103     {
104         *ppvObject = iface;
105     }
106     else
107         return E_NOINTERFACE;
108
109     IDispatch_AddRef( iface );
110
111     return S_OK;
112 }
113
114 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
115 {
116     dispevent *This = impl_from_IDispatch( iface );
117     return InterlockedIncrement( &This->ref );
118 }
119
120 static ULONG WINAPI dispevent_Release(IDispatch *iface)
121 {
122     dispevent *This = impl_from_IDispatch( iface );
123     ULONG ref = InterlockedDecrement( &This->ref );
124
125     if (ref == 0)
126         HeapFree(GetProcessHeap(), 0, This);
127
128     return ref;
129 }
130
131 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
132 {
133     g_unexpectedcall++;
134     *pctinfo = 0;
135     return S_OK;
136 }
137
138 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
139         LCID lcid, ITypeInfo **ppTInfo)
140 {
141     g_unexpectedcall++;
142     return S_OK;
143 }
144
145 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
146         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
147 {
148     g_unexpectedcall++;
149     return S_OK;
150 }
151
152 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
153         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
154         EXCEPINFO *excepInfo, UINT *argErr)
155 {
156     ok(member == 0, "expected 0 member, got %d\n", member);
157     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
158     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
159
160     ok(params->cArgs == 0, "got %d\n", params->cArgs);
161     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
162     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
163     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
164
165     ok(result == NULL, "got %p\n", result);
166     ok(excepInfo == NULL, "got %p\n", excepInfo);
167     ok(argErr == NULL, "got %p\n", argErr);
168
169     g_expectedcall++;
170     return E_FAIL;
171 }
172
173 static const IDispatchVtbl dispeventVtbl =
174 {
175     dispevent_QueryInterface,
176     dispevent_AddRef,
177     dispevent_Release,
178     dispevent_GetTypeInfoCount,
179     dispevent_GetTypeInfo,
180     dispevent_GetIDsOfNames,
181     dispevent_Invoke
182 };
183
184 static IDispatch* create_dispevent(void)
185 {
186     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
187
188     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
189     event->ref = 1;
190
191     return (IDispatch*)&event->IDispatch_iface;
192 }
193
194 /* object site */
195 DEFINE_EXPECT(site_qi_IServiceProvider);
196 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
197 DEFINE_EXPECT(site_qi_IOleClientSite);
198
199 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
200 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
201 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
202 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
203 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
204
205 DEFINE_EXPECT(htmldoc2_get_all);
206 DEFINE_EXPECT(htmldoc2_get_url);
207 DEFINE_EXPECT(collection_get_length);
208
209 typedef struct
210 {
211     IServiceProvider IServiceProvider_iface;
212 } testprov_t;
213
214 testprov_t testprov;
215
216 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
217 {
218     *ppvObject = NULL;
219
220     if (IsEqualGUID(riid, &IID_IServiceProvider))
221         CHECK_EXPECT2(site_qi_IServiceProvider);
222
223     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
224         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
225
226     if (IsEqualGUID(riid, &IID_IOleClientSite))
227         CHECK_EXPECT2(site_qi_IOleClientSite);
228
229     if (IsEqualGUID(riid, &IID_IUnknown))
230          *ppvObject = iface;
231     else if (IsEqualGUID(riid, &IID_IServiceProvider))
232          *ppvObject = &testprov.IServiceProvider_iface;
233
234     if (*ppvObject) IUnknown_AddRef(iface);
235
236     return *ppvObject ? S_OK : E_NOINTERFACE;
237 }
238
239 static ULONG WINAPI site_AddRef(IUnknown *iface)
240 {
241     return 2;
242 }
243
244 static ULONG WINAPI site_Release(IUnknown *iface)
245 {
246     return 1;
247 }
248
249 static const IUnknownVtbl testsiteVtbl =
250 {
251     site_QueryInterface,
252     site_AddRef,
253     site_Release
254 };
255
256 typedef struct
257 {
258     IUnknown IUnknown_iface;
259 } testsite_t;
260
261 static testsite_t testsite = { { &testsiteVtbl } };
262
263 /* test IHTMLElementCollection */
264 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
265 {
266     ok(0, "unexpected call\n");
267     *ppvObject = NULL;
268     return E_NOINTERFACE;
269 }
270
271 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
272 {
273     return 2;
274 }
275
276 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
277 {
278     return 1;
279 }
280
281 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
282 {
283     ok(0, "unexpected call\n");
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
288                                                 LCID lcid, ITypeInfo **ppTInfo)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
295                                                 LPOLESTR *rgszNames, UINT cNames,
296                                                 LCID lcid, DISPID *rgDispId)
297 {
298     ok(0, "unexpected call\n");
299     return E_NOTIMPL;
300 }
301
302 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
303                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
304                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
305 {
306     ok(0, "unexpected call\n");
307     return E_NOTIMPL;
308 }
309
310 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
311 {
312     ok(0, "unexpected call\n");
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
317 {
318     ok(0, "unexpected call\n");
319     return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
323 {
324     CHECK_EXPECT2(collection_get_length);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
329 {
330     ok(0, "unexpected call\n");
331     return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
335 {
336     ok(0, "unexpected call\n");
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
341 {
342     ok(0, "unexpected call\n");
343     return E_NOTIMPL;
344 }
345
346 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
347     htmlecoll_QueryInterface,
348     htmlecoll_AddRef,
349     htmlecoll_Release,
350     htmlecoll_GetTypeInfoCount,
351     htmlecoll_GetTypeInfo,
352     htmlecoll_GetIDsOfNames,
353     htmlecoll_Invoke,
354
355     htmlecoll_toString,
356     htmlecoll_put_length,
357     htmlecoll_get_length,
358     htmlecoll_get__newEnum,
359     htmlecoll_item,
360     htmlecoll_tags
361 };
362
363 typedef struct
364 {
365     IHTMLElementCollection IHTMLElementCollection_iface;
366 } testhtmlecoll_t;
367
368 static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
369
370 /* test IHTMLDocument2 */
371 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
372 {
373    trace("\n");
374    *ppvObject = NULL;
375    return E_NOINTERFACE;
376 }
377
378 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
379 {
380     return 2;
381 }
382
383 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
384 {
385     return 1;
386 }
387
388 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
389 {
390     ok(0, "unexpected call\n");
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
395                                                 LCID lcid, ITypeInfo **ppTInfo)
396 {
397     ok(0, "unexpected call\n");
398     return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
402                                                 LPOLESTR *rgszNames, UINT cNames,
403                                                 LCID lcid, DISPID *rgDispId)
404 {
405     ok(0, "unexpected call\n");
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
410                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
411                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
412 {
413     ok(0, "unexpected call\n");
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
418 {
419     ok(0, "unexpected call\n");
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
424 {
425     CHECK_EXPECT2(htmldoc2_get_all);
426     *p = &htmlecoll.IHTMLElementCollection_iface;
427     return S_OK;
428 }
429
430 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
431 {
432     ok(0, "unexpected call\n");
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
437 {
438     ok(0, "unexpected call\n");
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
443 {
444     ok(0, "unexpected call\n");
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
449 {
450     ok(0, "unexpected call\n");
451     return E_NOTIMPL;
452 }
453
454 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
455 {
456     ok(0, "unexpected call\n");
457     return E_NOTIMPL;
458 }
459
460 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
461 {
462     ok(0, "unexpected call\n");
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
467 {
468     ok(0, "unexpected call\n");
469     return E_NOTIMPL;
470 }
471
472 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
473 {
474     ok(0, "unexpected call\n");
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
479 {
480     ok(0, "unexpected call\n");
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
485 {
486     ok(0, "unexpected call\n");
487     return E_NOTIMPL;
488 }
489
490 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
491 {
492     ok(0, "unexpected call\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
497 {
498     ok(0, "unexpected call\n");
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
503 {
504     ok(0, "unexpected call\n");
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
509 {
510     ok(0, "unexpected call\n");
511     return E_NOTIMPL;
512 }
513
514 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
515 {
516     ok(0, "unexpected call\n");
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
521 {
522     ok(0, "unexpected call\n");
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
527 {
528     ok(0, "unexpected call\n");
529     return E_NOTIMPL;
530 }
531
532 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
533 {
534     ok(0, "unexpected call\n");
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
539 {
540     ok(0, "unexpected call\n");
541     return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
545 {
546     ok(0, "unexpected call\n");
547     return E_NOTIMPL;
548 }
549
550 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
551 {
552     ok(0, "unexpected call\n");
553     return E_NOTIMPL;
554 }
555
556 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
557 {
558     ok(0, "unexpected call\n");
559     return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
563 {
564     ok(0, "unexpected call\n");
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
569 {
570     ok(0, "unexpected call\n");
571     return E_NOTIMPL;
572 }
573
574 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
575 {
576     ok(0, "unexpected call\n");
577     return E_NOTIMPL;
578 }
579
580 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
581 {
582     ok(0, "unexpected call\n");
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
587 {
588     ok(0, "unexpected call\n");
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
593 {
594     ok(0, "unexpected call\n");
595     return E_NOTIMPL;
596 }
597
598 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
599 {
600     ok(0, "unexpected call\n");
601     return E_NOTIMPL;
602 }
603
604 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
605 {
606     ok(0, "unexpected call\n");
607     return E_NOTIMPL;
608 }
609
610 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
611 {
612     ok(0, "unexpected call\n");
613     return E_NOTIMPL;
614 }
615
616 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
617 {
618     CHECK_EXPECT2(htmldoc2_get_url);
619     *p = SysAllocString(NULL);
620     return S_OK;
621 }
622
623 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
624 {
625     ok(0, "unexpected call\n");
626     return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
630 {
631     ok(0, "unexpected call\n");
632     return E_NOTIMPL;
633 }
634
635 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
636 {
637     ok(0, "unexpected call\n");
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
642 {
643     ok(0, "unexpected call\n");
644     return E_NOTIMPL;
645 }
646
647 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
648 {
649     ok(0, "unexpected call\n");
650     return E_NOTIMPL;
651 }
652
653 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
654 {
655     ok(0, "unexpected call\n");
656     return E_NOTIMPL;
657 }
658
659 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
660 {
661     ok(0, "unexpected call\n");
662     return E_NOTIMPL;
663 }
664
665 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
666 {
667     ok(0, "unexpected call\n");
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
672 {
673     ok(0, "unexpected call\n");
674     return E_NOTIMPL;
675 }
676
677 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
678 {
679     ok(0, "unexpected call\n");
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
684 {
685     ok(0, "unexpected call\n");
686     return E_NOTIMPL;
687 }
688
689 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
690 {
691     ok(0, "unexpected call\n");
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
696 {
697     ok(0, "unexpected call\n");
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
708 {
709     ok(0, "unexpected call\n");
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
714 {
715     ok(0, "unexpected call\n");
716     return E_NOTIMPL;
717 }
718
719 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
720 {
721     ok(0, "unexpected call\n");
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
726 {
727     ok(0, "unexpected call\n");
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
732 {
733     ok(0, "unexpected call\n");
734     return E_NOTIMPL;
735 }
736
737 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
738 {
739     ok(0, "unexpected call\n");
740     return E_NOTIMPL;
741 }
742
743 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
744                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
745 {
746     ok(0, "unexpected call\n");
747     return E_NOTIMPL;
748 }
749
750 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
751 {
752     ok(0, "unexpected call\n");
753     return E_NOTIMPL;
754 }
755
756 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
757 {
758     ok(0, "unexpected call\n");
759     return E_NOTIMPL;
760 }
761
762 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
763                                                         VARIANT_BOOL *pfRet)
764 {
765     ok(0, "unexpected call\n");
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
770                                                         VARIANT_BOOL *pfRet)
771 {
772     ok(0, "unexpected call\n");
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
777                                                         VARIANT_BOOL *pfRet)
778 {
779     ok(0, "unexpected call\n");
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
784                                                         VARIANT_BOOL *pfRet)
785 {
786     ok(0, "unexpected call\n");
787     return E_NOTIMPL;
788 }
789
790 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
791                                                         BSTR *pfRet)
792 {
793     ok(0, "unexpected call\n");
794     return E_NOTIMPL;
795 }
796
797 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
798                                                         VARIANT *pfRet)
799 {
800     ok(0, "unexpected call\n");
801     return E_NOTIMPL;
802 }
803
804 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
805                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
806 {
807     ok(0, "unexpected call\n");
808     return E_NOTIMPL;
809 }
810
811 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
812                                                         VARIANT_BOOL *pfRet)
813 {
814     ok(0, "unexpected call\n");
815     return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
819                                                  IHTMLElement **newElem)
820 {
821     ok(0, "unexpected call\n");
822     return E_NOTIMPL;
823 }
824
825 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
826 {
827     ok(0, "unexpected call\n");
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
832 {
833     ok(0, "unexpected call\n");
834     return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
838 {
839     ok(0, "unexpected call\n");
840     return E_NOTIMPL;
841 }
842
843 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
844 {
845     ok(0, "unexpected call\n");
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
850 {
851     ok(0, "unexpected call\n");
852     return E_NOTIMPL;
853 }
854
855 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
856 {
857     ok(0, "unexpected call\n");
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
862 {
863     ok(0, "unexpected call\n");
864     return E_NOTIMPL;
865 }
866
867 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
868 {
869     ok(0, "unexpected call\n");
870     return E_NOTIMPL;
871 }
872
873 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
874 {
875     ok(0, "unexpected call\n");
876     return E_NOTIMPL;
877 }
878
879 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
880 {
881     ok(0, "unexpected call\n");
882     return E_NOTIMPL;
883 }
884
885 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
886 {
887     ok(0, "unexpected call\n");
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
892 {
893     ok(0, "unexpected call\n");
894     return E_NOTIMPL;
895 }
896
897 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
898 {
899     ok(0, "unexpected call\n");
900     return E_NOTIMPL;
901 }
902
903 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
904 {
905     ok(0, "unexpected call\n");
906     return E_NOTIMPL;
907 }
908
909 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
910 {
911     ok(0, "unexpected call\n");
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
916 {
917     ok(0, "unexpected call\n");
918     return E_NOTIMPL;
919 }
920
921 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
922 {
923     ok(0, "unexpected call\n");
924     return E_NOTIMPL;
925 }
926
927 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
928 {
929     ok(0, "unexpected call\n");
930     return E_NOTIMPL;
931 }
932
933 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
934 {
935     ok(0, "unexpected call\n");
936     return E_NOTIMPL;
937 }
938
939 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
940 {
941     ok(0, "unexpected call\n");
942     return E_NOTIMPL;
943 }
944
945 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
946 {
947     ok(0, "unexpected call\n");
948     return E_NOTIMPL;
949 }
950
951 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
952 {
953     ok(0, "unexpected call\n");
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
958 {
959     ok(0, "unexpected call\n");
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
964 {
965     ok(0, "unexpected call\n");
966     return E_NOTIMPL;
967 }
968
969 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
970 {
971     ok(0, "unexpected call\n");
972     return E_NOTIMPL;
973 }
974
975 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
976 {
977     ok(0, "unexpected call\n");
978     return E_NOTIMPL;
979 }
980
981 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
982 {
983     ok(0, "unexpected call\n");
984     return E_NOTIMPL;
985 }
986
987 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
988 {
989     ok(0, "unexpected call\n");
990     return E_NOTIMPL;
991 }
992
993 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
994 {
995     ok(0, "unexpected call\n");
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
1000 {
1001     ok(0, "unexpected call\n");
1002     return E_NOTIMPL;
1003 }
1004
1005 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1006 {
1007     ok(0, "unexpected call\n");
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1012 {
1013     ok(0, "unexpected call\n");
1014     return E_NOTIMPL;
1015 }
1016
1017 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1018 {
1019     ok(0, "unexpected call\n");
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1024 {
1025     ok(0, "unexpected call\n");
1026     return E_NOTIMPL;
1027 }
1028
1029 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1030                                                         IHTMLElement **elementHit)
1031 {
1032     ok(0, "unexpected call\n");
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1037 {
1038     ok(0, "unexpected call\n");
1039     return E_NOTIMPL;
1040 }
1041
1042 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
1043                                                    IHTMLStyleSheetsCollection **p)
1044 {
1045     ok(0, "unexpected call\n");
1046     return E_NOTIMPL;
1047 }
1048
1049 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1050 {
1051     ok(0, "unexpected call\n");
1052     return E_NOTIMPL;
1053 }
1054
1055 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1056 {
1057     ok(0, "unexpected call\n");
1058     return E_NOTIMPL;
1059 }
1060
1061 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1062 {
1063     ok(0, "unexpected call\n");
1064     return E_NOTIMPL;
1065 }
1066
1067 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1068 {
1069     ok(0, "unexpected call\n");
1070     return E_NOTIMPL;
1071 }
1072
1073 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
1074 {
1075     ok(0, "unexpected call\n");
1076     return E_NOTIMPL;
1077 }
1078
1079 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1080                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1081 {
1082     ok(0, "unexpected call\n");
1083     return E_NOTIMPL;
1084 }
1085
1086 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
1087     htmldoc2_QueryInterface,
1088     htmldoc2_AddRef,
1089     htmldoc2_Release,
1090     htmldoc2_GetTypeInfoCount,
1091     htmldoc2_GetTypeInfo,
1092     htmldoc2_GetIDsOfNames,
1093     htmldoc2_Invoke,
1094     htmldoc2_get_Script,
1095     htmldoc2_get_all,
1096     htmldoc2_get_body,
1097     htmldoc2_get_activeElement,
1098     htmldoc2_get_images,
1099     htmldoc2_get_applets,
1100     htmldoc2_get_links,
1101     htmldoc2_get_forms,
1102     htmldoc2_get_anchors,
1103     htmldoc2_put_title,
1104     htmldoc2_get_title,
1105     htmldoc2_get_scripts,
1106     htmldoc2_put_designMode,
1107     htmldoc2_get_designMode,
1108     htmldoc2_get_selection,
1109     htmldoc2_get_readyState,
1110     htmldoc2_get_frames,
1111     htmldoc2_get_embeds,
1112     htmldoc2_get_plugins,
1113     htmldoc2_put_alinkColor,
1114     htmldoc2_get_alinkColor,
1115     htmldoc2_put_bgColor,
1116     htmldoc2_get_bgColor,
1117     htmldoc2_put_fgColor,
1118     htmldoc2_get_fgColor,
1119     htmldoc2_put_linkColor,
1120     htmldoc2_get_linkColor,
1121     htmldoc2_put_vlinkColor,
1122     htmldoc2_get_vlinkColor,
1123     htmldoc2_get_referrer,
1124     htmldoc2_get_location,
1125     htmldoc2_get_lastModified,
1126     htmldoc2_put_URL,
1127     htmldoc2_get_URL,
1128     htmldoc2_put_domain,
1129     htmldoc2_get_domain,
1130     htmldoc2_put_cookie,
1131     htmldoc2_get_cookie,
1132     htmldoc2_put_expando,
1133     htmldoc2_get_expando,
1134     htmldoc2_put_charset,
1135     htmldoc2_get_charset,
1136     htmldoc2_put_defaultCharset,
1137     htmldoc2_get_defaultCharset,
1138     htmldoc2_get_mimeType,
1139     htmldoc2_get_fileSize,
1140     htmldoc2_get_fileCreatedDate,
1141     htmldoc2_get_fileModifiedDate,
1142     htmldoc2_get_fileUpdatedDate,
1143     htmldoc2_get_security,
1144     htmldoc2_get_protocol,
1145     htmldoc2_get_nameProp,
1146     htmldoc2_write,
1147     htmldoc2_writeln,
1148     htmldoc2_open,
1149     htmldoc2_close,
1150     htmldoc2_clear,
1151     htmldoc2_queryCommandSupported,
1152     htmldoc2_queryCommandEnabled,
1153     htmldoc2_queryCommandState,
1154     htmldoc2_queryCommandIndeterm,
1155     htmldoc2_queryCommandText,
1156     htmldoc2_queryCommandValue,
1157     htmldoc2_execCommand,
1158     htmldoc2_execCommandShowHelp,
1159     htmldoc2_createElement,
1160     htmldoc2_put_onhelp,
1161     htmldoc2_get_onhelp,
1162     htmldoc2_put_onclick,
1163     htmldoc2_get_onclick,
1164     htmldoc2_put_ondblclick,
1165     htmldoc2_get_ondblclick,
1166     htmldoc2_put_onkeyup,
1167     htmldoc2_get_onkeyup,
1168     htmldoc2_put_onkeydown,
1169     htmldoc2_get_onkeydown,
1170     htmldoc2_put_onkeypress,
1171     htmldoc2_get_onkeypress,
1172     htmldoc2_put_onmouseup,
1173     htmldoc2_get_onmouseup,
1174     htmldoc2_put_onmousedown,
1175     htmldoc2_get_onmousedown,
1176     htmldoc2_put_onmousemove,
1177     htmldoc2_get_onmousemove,
1178     htmldoc2_put_onmouseout,
1179     htmldoc2_get_onmouseout,
1180     htmldoc2_put_onmouseover,
1181     htmldoc2_get_onmouseover,
1182     htmldoc2_put_onreadystatechange,
1183     htmldoc2_get_onreadystatechange,
1184     htmldoc2_put_onafterupdate,
1185     htmldoc2_get_onafterupdate,
1186     htmldoc2_put_onrowexit,
1187     htmldoc2_get_onrowexit,
1188     htmldoc2_put_onrowenter,
1189     htmldoc2_get_onrowenter,
1190     htmldoc2_put_ondragstart,
1191     htmldoc2_get_ondragstart,
1192     htmldoc2_put_onselectstart,
1193     htmldoc2_get_onselectstart,
1194     htmldoc2_elementFromPoint,
1195     htmldoc2_get_parentWindow,
1196     htmldoc2_get_styleSheets,
1197     htmldoc2_put_onbeforeupdate,
1198     htmldoc2_get_onbeforeupdate,
1199     htmldoc2_put_onerrorupdate,
1200     htmldoc2_get_onerrorupdate,
1201     htmldoc2_toString,
1202     htmldoc2_createStyleSheet
1203 };
1204
1205 typedef struct
1206 {
1207     IHTMLDocument2 IHTMLDocument2_iface;
1208 } testhtmldoc2_t;
1209
1210 static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
1211
1212 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1213 {
1214     *ppvObject = NULL;
1215
1216     if (IsEqualGUID(riid, &IID_IUnknown) ||
1217         IsEqualGUID(riid, &IID_IServiceProvider))
1218     {
1219         *ppvObject = iface;
1220         IServiceProvider_AddRef(iface);
1221         return S_OK;
1222     }
1223
1224     ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
1225
1226     return E_NOINTERFACE;
1227 }
1228
1229 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1230 {
1231     return 2;
1232 }
1233
1234 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1235 {
1236     return 1;
1237 }
1238
1239 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1240 {
1241     *obj = NULL;
1242
1243     if (IsEqualGUID(service, &SID_SBindHost) &&
1244         IsEqualGUID(riid, &IID_IBindHost))
1245     {
1246         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1247     }
1248     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1249              IsEqualGUID(riid, &IID_IHTMLDocument2))
1250     {
1251         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1252     }
1253     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1254              IsEqualGUID(riid, &IID_IHTMLDocument2))
1255     {
1256         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1257         *obj = &htmldoc2.IHTMLDocument2_iface;
1258         return S_OK;
1259     }
1260     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1261              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1262     {
1263         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1264     }
1265     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1266              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1267     {
1268         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1269     }
1270     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1271              IsEqualGUID(riid, &IID_IStream))
1272     {
1273         /* FIXME: unidentified service id */
1274     }
1275     else
1276         ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
1277
1278     return E_NOTIMPL;
1279 }
1280
1281 static const IServiceProviderVtbl testprovVtbl =
1282 {
1283     sp_QueryInterface,
1284     sp_AddRef,
1285     sp_Release,
1286     sp_QueryService
1287 };
1288
1289 testprov_t testprov = { { &testprovVtbl } };
1290
1291 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1292 static void _expect_children(IXMLDOMNode *node, int line)
1293 {
1294     VARIANT_BOOL b;
1295     HRESULT hr;
1296
1297     b = VARIANT_FALSE;
1298     hr = IXMLDOMNode_hasChildNodes(node, &b);
1299     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1300     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1301 }
1302
1303 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1304 static void _expect_no_children(IXMLDOMNode *node, int line)
1305 {
1306     VARIANT_BOOL b;
1307     HRESULT hr;
1308
1309     b = VARIANT_TRUE;
1310     hr = IXMLDOMNode_hasChildNodes(node, &b);
1311     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1312     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1313 }
1314
1315 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1316 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1317 {
1318     ULONG rc = IUnknown_AddRef(obj);
1319     IUnknown_Release(obj);
1320     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1321 }
1322
1323 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1324 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1325 {
1326     LONG length;
1327     HRESULT hr;
1328
1329     length = 0;
1330     hr = IXMLDOMNodeList_get_length(list, &length);
1331     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1332     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1333 }
1334
1335 #define EXPECT_HR(hr,hr_exp) \
1336     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1337
1338 static const WCHAR szEmpty[] = { 0 };
1339 static const WCHAR szIncomplete[] = {
1340     '<','?','x','m','l',' ',
1341     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1342 };
1343 static const WCHAR szComplete1[] = {
1344     '<','?','x','m','l',' ',
1345     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1346     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1347 };
1348 static const WCHAR szComplete2[] = {
1349     '<','?','x','m','l',' ',
1350     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1351     '<','o','>','<','/','o','>','\n',0
1352 };
1353 static const WCHAR szComplete3[] = {
1354     '<','?','x','m','l',' ',
1355     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1356     '<','a','>','<','/','a','>','\n',0
1357 };
1358 static const char complete4A[] =
1359     "<?xml version=\'1.0\'?>\n"
1360     "<lc dl=\'str1\'>\n"
1361         "<bs vr=\'str2\' sz=\'1234\'>"
1362             "fn1.txt\n"
1363         "</bs>\n"
1364         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1365             "fn2.txt\n"
1366         "</pr>\n"
1367         "<empty></empty>\n"
1368         "<fo>\n"
1369             "<ba>\n"
1370                 "f1\n"
1371             "</ba>\n"
1372         "</fo>\n"
1373     "</lc>\n";
1374
1375 static const WCHAR szComplete5[] = {
1376     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1377     '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','"',
1378     ' ','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','"','>',
1379         '<','S',':','s','c','o','p','e','>',
1380             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1381         '<','/','S',':','s','c','o','p','e','>',
1382         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1383             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1384             'c','o','m','p','u','t','e','r',
1385         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1386     '<','/','S',':','s','e','a','r','c','h','>',0
1387 };
1388
1389 static const WCHAR szComplete6[] = {
1390     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1391     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1392     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1393 };
1394
1395 static const CHAR szNonUnicodeXML[] =
1396 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1397 "<open></open>\n";
1398
1399 static const char szExampleXML[] =
1400 "<?xml version='1.0' encoding='utf-8'?>\n"
1401 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1402 "    <elem>\n"
1403 "        <a>A1 field</a>\n"
1404 "        <b>B1 field</b>\n"
1405 "        <c>C1 field</c>\n"
1406 "        <d>D1 field</d>\n"
1407 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1408 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1409 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1410 "            </html>\n"
1411 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1412 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1413 "            </html>\n"
1414 "        </description>\n"
1415 "    </elem>\n"
1416 "\n"
1417 "    <elem>\n"
1418 "        <a>A2 field</a>\n"
1419 "        <b>B2 field</b>\n"
1420 "        <c type=\"old\">C2 field</c>\n"
1421 "        <d>D2 field</d>\n"
1422 "    </elem>\n"
1423 "\n"
1424 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1425 "        <a>A3 field</a>\n"
1426 "        <b>B3 field</b>\n"
1427 "        <c>C3 field</c>\n"
1428 "    </elem>\n"
1429 "\n"
1430 "    <elem>\n"
1431 "        <a>A4 field</a>\n"
1432 "        <b>B4 field</b>\n"
1433 "        <foo:c>C4 field</foo:c>\n"
1434 "        <d>D4 field</d>\n"
1435 "    </elem>\n"
1436 "</root>\n";
1437
1438 static const CHAR szNodeTypesXML[] =
1439 "<?xml version='1.0'?>"
1440 "<!-- comment node 0 -->"
1441 "<root id='0' depth='0'>"
1442 "   <!-- comment node 1 -->"
1443 "   text node 0"
1444 "   <x id='1' depth='1'>"
1445 "       <?foo value='PI for x'?>"
1446 "       <!-- comment node 2 -->"
1447 "       text node 1"
1448 "       <a id='3' depth='2'/>"
1449 "       <b id='4' depth='2'/>"
1450 "       <c id='5' depth='2'/>"
1451 "   </x>"
1452 "   <y id='2' depth='1'>"
1453 "       <?bar value='PI for y'?>"
1454 "       <!-- comment node 3 -->"
1455 "       text node 2"
1456 "       <a id='6' depth='2'/>"
1457 "       <b id='7' depth='2'/>"
1458 "       <c id='8' depth='2'/>"
1459 "   </y>"
1460 "</root>";
1461
1462 static const CHAR szTransformXML[] =
1463 "<?xml version=\"1.0\"?>\n"
1464 "<greeting>\n"
1465 "Hello World\n"
1466 "</greeting>";
1467
1468 static  const CHAR szTransformSSXML[] =
1469 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1470 "   <xsl:output method=\"html\"/>\n"
1471 "   <xsl:template match=\"/\">\n"
1472 "       <xsl:apply-templates select=\"greeting\"/>\n"
1473 "   </xsl:template>\n"
1474 "   <xsl:template match=\"greeting\">\n"
1475 "       <html>\n"
1476 "           <body>\n"
1477 "               <h1>\n"
1478 "                   <xsl:value-of select=\".\"/>\n"
1479 "               </h1>\n"
1480 "           </body>\n"
1481 "       </html>\n"
1482 "   </xsl:template>\n"
1483 "</xsl:stylesheet>";
1484
1485 static  const CHAR szTransformOutput[] =
1486 "<html><body><h1>"
1487 "Hello World"
1488 "</h1></body></html>";
1489
1490 static const CHAR szTypeValueXML[] =
1491 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1492 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1493 "   <string>Wine</string>\n"
1494 "   <string2 dt:dt=\"string\">String</string2>\n"
1495 "   <number dt:dt=\"number\">12.44</number>\n"
1496 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1497 "   <int dt:dt=\"int\">-13</int>\n"
1498 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1499 "   <bool dt:dt=\"boolean\">1</bool>\n"
1500 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1501 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1502 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1503 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1504 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1505 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1506 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1507 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1508 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1509 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1510 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1511 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1512 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1513 "   <float dt:dt=\"float\">41221.421</float>\n"
1514 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1515 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1516 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1517 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1518 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1519 "</root>";
1520
1521 static const CHAR szBasicTransformSSXMLPart1[] =
1522 "<?xml version=\"1.0\"?>"
1523 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1524 "<xsl:output method=\"html\"/>\n"
1525 "<xsl:template match=\"/\">"
1526 "<HTML><BODY><TABLE>"
1527 "        <xsl:apply-templates select='document(\"";
1528
1529 static const CHAR szBasicTransformSSXMLPart2[] =
1530 "\")/bottle/wine'>"
1531 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1532 "        </xsl:apply-templates>"
1533 "</TABLE></BODY></HTML>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"bottle\">"
1536 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1537 "</xsl:template>"
1538 "<xsl:template match=\"name\">"
1539 "   <TD><xsl:apply-templates /></TD>"
1540 "</xsl:template>"
1541 "<xsl:template match=\"cost\">"
1542 "   <TD><xsl:apply-templates /></TD>"
1543 "</xsl:template>"
1544 "</xsl:stylesheet>";
1545
1546 static const CHAR szBasicTransformXML[] =
1547 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1548
1549 static const CHAR szBasicTransformOutput[] =
1550 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1551
1552 #define SZ_EMAIL_DTD \
1553 "<!DOCTYPE email ["\
1554 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1555 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1556 "       <!ATTLIST email sent (yes|no) \"no\">"\
1557 "   <!ELEMENT recipients    (to+,cc*)>"\
1558 "   <!ELEMENT to            (#PCDATA)>"\
1559 "       <!ATTLIST to name CDATA #IMPLIED>"\
1560 "   <!ELEMENT cc            (#PCDATA)>"\
1561 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1562 "   <!ELEMENT from          (#PCDATA)>"\
1563 "       <!ATTLIST from name CDATA #IMPLIED>"\
1564 "   <!ELEMENT reply-to      (#PCDATA)>"\
1565 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1566 "   <!ELEMENT subject       ANY>"\
1567 "   <!ELEMENT body          ANY>"\
1568 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1569 "   <!ELEMENT attachment    (#PCDATA)>"\
1570 "       <!ATTLIST attachment id ID #REQUIRED>"\
1571 "]>"
1572
1573 static const CHAR szEmailXML[] =
1574 "<?xml version=\"1.0\"?>"
1575 SZ_EMAIL_DTD
1576 "<email attachments=\"patch1\">"
1577 "   <recipients>"
1578 "       <to>wine-patches@winehq.org</to>"
1579 "   </recipients>"
1580 "   <from name=\"Anonymous\">user@localhost</from>"
1581 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1582 "   <body>"
1583 "       It no longer causes spontaneous combustion..."
1584 "   </body>"
1585 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1586 "</email>";
1587
1588 static const CHAR szEmailXML_0D[] =
1589 "<?xml version=\"1.0\"?>"
1590 SZ_EMAIL_DTD
1591 "<email attachments=\"patch1\">"
1592 "   <recipients>"
1593 "       <to>wine-patches@winehq.org</to>"
1594 "   </recipients>"
1595 "   <from name=\"Anonymous\">user@localhost</from>"
1596 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1597 "   <body>"
1598 "       <undecl />"
1599 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1600 "   </body>"
1601 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1602 "</email>";
1603
1604 static const CHAR szEmailXML_0E[] =
1605 "<?xml version=\"1.0\"?>"
1606 SZ_EMAIL_DTD
1607 "<email attachments=\"patch1\">"
1608 "   <recipients>"
1609 "       <to>wine-patches@winehq.org</to>"
1610 "   </recipients>"
1611 "   <from name=\"Anonymous\">user@localhost</from>"
1612 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1613 "   <body>"
1614 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1615 "   </body>"
1616 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1617 "</email>";
1618
1619 static const CHAR szEmailXML_11[] =
1620 "<?xml version=\"1.0\"?>"
1621 SZ_EMAIL_DTD
1622 "<email attachments=\"patch1\">"
1623 "   <recipients>"
1624 "   </recipients>"
1625 "   <from name=\"Anonymous\">user@localhost</from>"
1626 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1627 "   <body>"
1628 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1629 "   </body>"
1630 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1631 "</email>";
1632
1633 static const CHAR szEmailXML_13[] =
1634 "<?xml version=\"1.0\"?>"
1635 SZ_EMAIL_DTD
1636 "<msg attachments=\"patch1\">"
1637 "   <recipients>"
1638 "       <to>wine-patches@winehq.org</to>"
1639 "   </recipients>"
1640 "   <from name=\"Anonymous\">user@localhost</from>"
1641 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1642 "   <body>"
1643 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1644 "   </body>"
1645 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1646 "</msg>";
1647
1648 static const CHAR szEmailXML_14[] =
1649 "<?xml version=\"1.0\"?>"
1650 SZ_EMAIL_DTD
1651 "<email attachments=\"patch1\">"
1652 "   <to>wine-patches@winehq.org</to>"
1653 "   <from name=\"Anonymous\">user@localhost</from>"
1654 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1655 "   <body>"
1656 "       XML_INVALID_CONTENT 0xC00CE014"
1657 "   </body>"
1658 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1659 "</email>";
1660
1661 static const CHAR szEmailXML_15[] =
1662 "<?xml version=\"1.0\"?>"
1663 SZ_EMAIL_DTD
1664 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1665 "   <recipients>"
1666 "       <to>wine-patches@winehq.org</to>"
1667 "   </recipients>"
1668 "   <from name=\"Anonymous\">user@localhost</from>"
1669 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1670 "   <body>"
1671 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1672 "   </body>"
1673 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1674 "</email>";
1675
1676 static const CHAR szEmailXML_16[] =
1677 "<?xml version=\"1.0\"?>"
1678 SZ_EMAIL_DTD
1679 "<email attachments=\"patch1\">"
1680 "   <recipients>"
1681 "       <to>wine-patches@winehq.org</to>"
1682 "   </recipients>"
1683 "   <from name=\"Anonymous\">user@localhost</from>"
1684 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1685 "   <body enc=\"ASCII\">"
1686 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1687 "   </body>"
1688 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1689 "</email>";
1690
1691 static const CHAR szEmailXML_17[] =
1692 "<?xml version=\"1.0\"?>"
1693 SZ_EMAIL_DTD
1694 "<email attachments=\"patch1\" sent=\"true\">"
1695 "   <recipients>"
1696 "       <to>wine-patches@winehq.org</to>"
1697 "   </recipients>"
1698 "   <from name=\"Anonymous\">user@localhost</from>"
1699 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1700 "   <body>"
1701 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1702 "   </body>"
1703 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1704 "</email>";
1705
1706 static const CHAR szEmailXML_18[] =
1707 "<?xml version=\"1.0\"?>"
1708 SZ_EMAIL_DTD
1709 "<email attachments=\"patch1\">"
1710 "   oops"
1711 "   <recipients>"
1712 "       <to>wine-patches@winehq.org</to>"
1713 "   </recipients>"
1714 "   <from name=\"Anonymous\">user@localhost</from>"
1715 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1716 "   <body>"
1717 "       XML_ILLEGAL_TEXT 0xC00CE018"
1718 "   </body>"
1719 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1720 "</email>";
1721
1722 static const CHAR szEmailXML_20[] =
1723 "<?xml version=\"1.0\"?>"
1724 SZ_EMAIL_DTD
1725 "<email>"
1726 "   <recipients>"
1727 "       <to>wine-patches@winehq.org</to>"
1728 "   </recipients>"
1729 "   <from name=\"Anonymous\">user@localhost</from>"
1730 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1731 "   <body>"
1732 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1733 "   </body>"
1734 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1735 "</email>";
1736
1737 static const char xpath_simple_list[] =
1738 "<?xml version=\"1.0\"?>"
1739 "<root>"
1740 "   <a attr1=\"1\" attr2=\"2\" />"
1741 "   <b/>"
1742 "   <c/>"
1743 "   <d/>"
1744 "</root>";
1745
1746 static const char default_ns_doc[] = {
1747     "<?xml version=\"1.0\"?>"
1748     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1749     "    d=\"d attr\" />"
1750 };
1751
1752 static const WCHAR nonexistent_fileW[] = {
1753     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1754 };
1755 static const WCHAR nonexistent_attrW[] = {
1756     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1757 };
1758 static const WCHAR szDocument[] = {
1759     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1760 };
1761
1762 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1763 static WCHAR szdl[] = { 'd','l',0 };
1764 static const WCHAR szvr[] = { 'v','r',0 };
1765 static const WCHAR szlc[] = { 'l','c',0 };
1766 static WCHAR szbs[] = { 'b','s',0 };
1767 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1768 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1769 static const WCHAR szstar[] = { '*',0 };
1770 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1771
1772 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1773 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1774 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1775
1776 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1777 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1778 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1779 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1780                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1781 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1782                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1783
1784 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1785 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1786
1787 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1788                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1789 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1790                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1791                              '!',']',']','>',0};
1792 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1793 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1794
1795 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1796 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1797 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1798
1799 #define expect_bstr_eq_and_free(bstr, expect) { \
1800     BSTR bstrExp = alloc_str_from_narrow(expect); \
1801     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1802     SysFreeString(bstr); \
1803     SysFreeString(bstrExp); \
1804 }
1805
1806 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1807
1808 #define ole_check(expr) { \
1809     HRESULT r = expr; \
1810     ok(r == S_OK, #expr " returned %x\n", r); \
1811 }
1812
1813 #define ole_expect(expr, expect) { \
1814     HRESULT r = expr; \
1815     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1816 }
1817
1818 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1819
1820 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1821 {
1822     void *obj = NULL;
1823     HRESULT hr;
1824
1825     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1826     if (hr != S_OK)
1827         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1828
1829     return obj;
1830 }
1831
1832 #define _create(cls) cls, #cls
1833
1834 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1835 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1836 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1837 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1838 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1839
1840 static BSTR alloc_str_from_narrow(const char *str)
1841 {
1842     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1843     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1844     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1845     return ret;
1846 }
1847
1848 static BSTR alloced_bstrs[256];
1849 static int alloced_bstrs_count;
1850
1851 static BSTR _bstr_(const char *str)
1852 {
1853     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1854     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1855     return alloced_bstrs[alloced_bstrs_count++];
1856 }
1857
1858 static void free_bstrs(void)
1859 {
1860     int i;
1861     for (i = 0; i < alloced_bstrs_count; i++)
1862         SysFreeString(alloced_bstrs[i]);
1863     alloced_bstrs_count = 0;
1864 }
1865
1866 static VARIANT _variantbstr_(const char *str)
1867 {
1868     VARIANT v;
1869     V_VT(&v) = VT_BSTR;
1870     V_BSTR(&v) = _bstr_(str);
1871     return v;
1872 }
1873
1874 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1875 {
1876     for (;;)
1877     {
1878         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1879         while (*sRight == '\r' || *sRight == '\n') sRight++;
1880         if (*sLeft != *sRight) return FALSE;
1881         if (!*sLeft) return TRUE;
1882         sLeft++;
1883         sRight++;
1884     }
1885 }
1886
1887 static void get_str_for_type(DOMNodeType type, char *buf)
1888 {
1889     switch (type)
1890     {
1891         case NODE_ATTRIBUTE:
1892             strcpy(buf, "A");
1893             break;
1894         case NODE_ELEMENT:
1895             strcpy(buf, "E");
1896             break;
1897         case NODE_DOCUMENT:
1898             strcpy(buf, "D");
1899             break;
1900         case NODE_TEXT:
1901             strcpy(buf, "T");
1902             break;
1903         case NODE_COMMENT:
1904             strcpy(buf, "C");
1905             break;
1906         case NODE_PROCESSING_INSTRUCTION:
1907             strcpy(buf, "P");
1908             break;
1909         default:
1910             wsprintfA(buf, "[%d]", type);
1911     }
1912 }
1913
1914 static int get_node_position(IXMLDOMNode *node)
1915 {
1916     HRESULT r;
1917     int pos = 0;
1918
1919     IXMLDOMNode_AddRef(node);
1920     do
1921     {
1922         IXMLDOMNode *new_node;
1923
1924         pos++;
1925         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1926         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1927         IXMLDOMNode_Release(node);
1928         node = new_node;
1929     } while (r == S_OK);
1930     return pos;
1931 }
1932
1933 static void node_to_string(IXMLDOMNode *node, char *buf)
1934 {
1935     HRESULT r = S_OK;
1936     DOMNodeType type;
1937
1938     if (node == NULL)
1939     {
1940         lstrcpyA(buf, "(null)");
1941         return;
1942     }
1943
1944     IXMLDOMNode_AddRef(node);
1945     while (r == S_OK)
1946     {
1947         IXMLDOMNode *new_node;
1948
1949         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1950         get_str_for_type(type, buf);
1951         buf+=strlen(buf);
1952
1953         if (type == NODE_ATTRIBUTE)
1954         {
1955             BSTR bstr;
1956             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1957             *(buf++) = '\'';
1958             wsprintfA(buf, "%ws", bstr);
1959             buf += strlen(buf);
1960             *(buf++) = '\'';
1961             SysFreeString(bstr);
1962
1963             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1964         }
1965         else
1966         {
1967             r = IXMLDOMNode_get_parentNode(node, &new_node);
1968             wsprintf(buf, "%d", get_node_position(node));
1969             buf += strlen(buf);
1970         }
1971
1972         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1973         IXMLDOMNode_Release(node);
1974         node = new_node;
1975         if (r == S_OK)
1976             *(buf++) = '.';
1977     }
1978
1979     *buf = 0;
1980 }
1981
1982 static char *list_to_string(IXMLDOMNodeList *list)
1983 {
1984     static char buf[4096];
1985     char *pos = buf;
1986     LONG len = 0;
1987     int i;
1988
1989     if (list == NULL)
1990     {
1991         lstrcpyA(buf, "(null)");
1992         return buf;
1993     }
1994     ole_check(IXMLDOMNodeList_get_length(list, &len));
1995     for (i = 0; i < len; i++)
1996     {
1997         IXMLDOMNode *node;
1998         if (i > 0)
1999             *(pos++) = ' ';
2000         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2001         node_to_string(node, pos);
2002         pos += strlen(pos);
2003         IXMLDOMNode_Release(node);
2004     }
2005     *pos = 0;
2006     return buf;
2007 }
2008
2009 #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); }
2010 #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); }
2011
2012 struct docload_ret_t {
2013     VARIANT_BOOL b;
2014     HRESULT hr;
2015 };
2016
2017 struct leading_spaces_t {
2018     const CLSID *clsid;
2019     const char *name;
2020     struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
2021 };
2022
2023 static const struct leading_spaces_t leading_spaces_classdata[] = {
2024     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2025     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2026     { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2027     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2028     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2029     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2030     { NULL }
2031 };
2032
2033 static const char* leading_spaces_xmldata[] = {
2034     "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
2035     " <?xml version=\"1.0\"?><root/>",
2036     "\n<?xml version=\"1.0\"?><root/>",
2037     "\t<?xml version=\"1.0\"?><root/>",
2038     "\r\n<?xml version=\"1.0\"?><root/>",
2039     "\r<?xml version=\"1.0\"?><root/>",
2040     "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
2041     0
2042 };
2043
2044 static void test_domdoc( void )
2045 {
2046     HRESULT r, hr;
2047     IXMLDOMDocument *doc;
2048     IXMLDOMParseError *error;
2049     IXMLDOMElement *element = NULL;
2050     IXMLDOMNode *node;
2051     IXMLDOMText *nodetext = NULL;
2052     IXMLDOMComment *node_comment = NULL;
2053     IXMLDOMAttribute *node_attr = NULL;
2054     IXMLDOMNode *nodeChild = NULL;
2055     IXMLDOMProcessingInstruction *nodePI = NULL;
2056     const struct leading_spaces_t *class_ptr;
2057     const char **data_ptr;
2058     VARIANT_BOOL b;
2059     VARIANT var;
2060     BSTR str;
2061     LONG code, ref;
2062     LONG nLength = 0;
2063     WCHAR buff[100];
2064     char path[MAX_PATH];
2065     int index;
2066
2067     GetTempPathA(MAX_PATH, path);
2068     strcat(path, "leading_spaces.xml");
2069
2070     /* Load document with leading spaces
2071      *
2072      * Test all CLSIDs with all test data XML strings
2073      */
2074     class_ptr = leading_spaces_classdata;
2075     index = 0;
2076     while (class_ptr->clsid)
2077     {
2078         HRESULT hr;
2079         int i;
2080
2081         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
2082              &IID_IXMLDOMDocument, (void**)&doc);
2083         if (hr != S_OK) {
2084             win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
2085             class_ptr++;
2086             index++;
2087             continue;
2088         }
2089
2090         data_ptr = leading_spaces_xmldata;
2091         i = 0;
2092         while (*data_ptr) {
2093             BSTR data = _bstr_(*data_ptr);
2094             DWORD written;
2095             HANDLE file;
2096
2097             file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2098             ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
2099
2100             WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
2101             CloseHandle(file);
2102
2103             b = 0xc;
2104             V_VT(&var) = VT_BSTR;
2105             V_BSTR(&var) = _bstr_(path);
2106             hr = IXMLDOMDocument_load(doc, var, &b);
2107         todo_wine {
2108             EXPECT_HR(hr, class_ptr->ret[0].hr);
2109             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
2110         }
2111             DeleteFileA(path);
2112
2113             b = 0xc;
2114             hr = IXMLDOMDocument_loadXML(doc, data, &b);
2115             EXPECT_HR(hr, class_ptr->ret[1].hr);
2116             ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
2117
2118             data_ptr++;
2119             i++;
2120         }
2121
2122         class_ptr++;
2123         index++;
2124         free_bstrs();
2125     }
2126
2127     doc = create_document(&IID_IXMLDOMDocument);
2128     if (!doc) return;
2129
2130 if (0)
2131 {
2132     /* crashes on native */
2133     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2134 }
2135
2136     /* try some stupid things */
2137     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2138     EXPECT_HR(hr, S_FALSE);
2139
2140     b = VARIANT_TRUE;
2141     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2142     EXPECT_HR(hr, S_FALSE);
2143     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2144
2145     /* try to load a document from a nonexistent file */
2146     b = VARIANT_TRUE;
2147     str = SysAllocString( nonexistent_fileW );
2148     VariantInit(&var);
2149     V_VT(&var) = VT_BSTR;
2150     V_BSTR(&var) = str;
2151
2152     r = IXMLDOMDocument_load( doc, var, &b);
2153     ok( r == S_FALSE, "loadXML succeeded\n");
2154     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2155     SysFreeString( str );
2156
2157     /* try load an empty document */
2158     b = VARIANT_TRUE;
2159     str = SysAllocString( szEmpty );
2160     r = IXMLDOMDocument_loadXML( doc, str, &b );
2161     ok( r == S_FALSE, "loadXML succeeded\n");
2162     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2163     SysFreeString( str );
2164
2165     r = IXMLDOMDocument_get_async( doc, &b );
2166     ok( r == S_OK, "get_async failed (%08x)\n", r);
2167     ok( b == VARIANT_TRUE, "Wrong default value\n");
2168
2169     /* check that there's no document element */
2170     element = NULL;
2171     r = IXMLDOMDocument_get_documentElement( doc, &element );
2172     ok( r == S_FALSE, "should be no document element\n");
2173
2174     /* try finding a node */
2175     node = NULL;
2176     str = SysAllocString( szstr1 );
2177     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2178     ok( r == S_FALSE, "ret %08x\n", r );
2179     SysFreeString( str );
2180
2181     b = VARIANT_TRUE;
2182     str = SysAllocString( szIncomplete );
2183     r = IXMLDOMDocument_loadXML( doc, str, &b );
2184     ok( r == S_FALSE, "loadXML succeeded\n");
2185     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2186     SysFreeString( str );
2187
2188     /* check that there's no document element */
2189     element = (IXMLDOMElement*)1;
2190     r = IXMLDOMDocument_get_documentElement( doc, &element );
2191     ok( r == S_FALSE, "should be no document element\n");
2192     ok( element == NULL, "Element should be NULL\n");
2193
2194     /* test for BSTR handling, pass broken BSTR */
2195     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2196     /* just a big length */
2197     *(DWORD*)buff = 0xf0f0;
2198     b = VARIANT_FALSE;
2199     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2200     ok( r == S_OK, "loadXML failed\n");
2201     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2202
2203     /* loadXML ignores the encoding attribute and always expects Unicode */
2204     b = VARIANT_FALSE;
2205     str = SysAllocString( szComplete6 );
2206     r = IXMLDOMDocument_loadXML( doc, str, &b );
2207     ok( r == S_OK, "loadXML failed\n");
2208     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2209     SysFreeString( str );
2210
2211     /* try a BSTR containing a Windows-1252 document */
2212     b = VARIANT_TRUE;
2213     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2214     r = IXMLDOMDocument_loadXML( doc, str, &b );
2215     ok( r == S_FALSE, "loadXML succeeded\n");
2216     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2217     SysFreeString( str );
2218
2219     /* try to load something valid */
2220     b = VARIANT_FALSE;
2221     str = SysAllocString( szComplete1 );
2222     r = IXMLDOMDocument_loadXML( doc, str, &b );
2223     ok( r == S_OK, "loadXML failed\n");
2224     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2225     SysFreeString( str );
2226
2227     /* check if nodename is correct */
2228     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2229     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2230
2231     str = (BSTR)0xdeadbeef;
2232     r = IXMLDOMDocument_get_baseName( doc, &str );
2233     ok ( r == S_FALSE, "got 0x%08x\n", r);
2234     ok (str == NULL, "got %p\n", str);
2235
2236     /* content doesn't matter here */
2237     str = NULL;
2238     r = IXMLDOMDocument_get_nodeName( doc, &str );
2239     ok ( r == S_OK, "get_nodeName wrong code\n");
2240     ok ( str != NULL, "str is null\n");
2241     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2242     SysFreeString( str );
2243
2244     /* test put_text */
2245     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2246     ok( r == E_FAIL, "ret %08x\n", r );
2247
2248     /* check that there's a document element */
2249     element = NULL;
2250     r = IXMLDOMDocument_get_documentElement( doc, &element );
2251     ok( r == S_OK, "should be a document element\n");
2252     if( element )
2253     {
2254         IObjectIdentity *ident;
2255
2256         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2257         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2258
2259         IXMLDOMElement_Release( element );
2260         element = NULL;
2261     }
2262
2263     /* as soon as we call loadXML again, the document element will disappear */
2264     b = 2;
2265     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2266     ok( r == S_FALSE, "loadXML failed\n");
2267     ok( b == 2, "variant modified\n");
2268     r = IXMLDOMDocument_get_documentElement( doc, &element );
2269     ok( r == S_FALSE, "should be no document element\n");
2270
2271     /* try to load something else simple and valid */
2272     b = VARIANT_FALSE;
2273     str = SysAllocString( szComplete3 );
2274     r = IXMLDOMDocument_loadXML( doc, str, &b );
2275     ok( r == S_OK, "loadXML failed\n");
2276     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2277     SysFreeString( str );
2278
2279     /* try something a little more complicated */
2280     b = FALSE;
2281     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2282     ok( r == S_OK, "loadXML failed\n");
2283     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2284
2285     r = IXMLDOMDocument_get_parseError( doc, &error );
2286     ok( r == S_OK, "returns %08x\n", r );
2287
2288     r = IXMLDOMParseError_get_errorCode( error, &code );
2289     ok( r == S_FALSE, "returns %08x\n", r );
2290     ok( code == 0, "code %d\n", code );
2291     IXMLDOMParseError_Release( error );
2292
2293     /* test createTextNode */
2294     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2295     ok( r == S_OK, "returns %08x\n", r );
2296     IXMLDOMText_Release(nodetext);
2297
2298     str = SysAllocString( szOpen );
2299     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2300     ok( r == E_INVALIDARG, "returns %08x\n", r );
2301     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2302     ok( r == S_OK, "returns %08x\n", r );
2303     SysFreeString( str );
2304     if(nodetext)
2305     {
2306         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2307         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2308
2309         /* Text Last Child Checks */
2310         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2311         ok(r == E_INVALIDARG, "ret %08x\n", r );
2312
2313         nodeChild = (IXMLDOMNode*)0x1;
2314         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2315         ok(r == S_FALSE, "ret %08x\n", r );
2316         ok(nodeChild == NULL, "nodeChild not NULL\n");
2317
2318         /* test length property */
2319         r = IXMLDOMText_get_length(nodetext, NULL);
2320         ok(r == E_INVALIDARG, "ret %08x\n", r );
2321
2322         r = IXMLDOMText_get_length(nodetext, &nLength);
2323         ok(r == S_OK, "ret %08x\n", r );
2324         ok(nLength == 4, "expected 4 got %d\n", nLength);
2325
2326         /* put data Tests */
2327         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2328         ok(r == S_OK, "ret %08x\n", r );
2329
2330         /* get data Tests */
2331         r = IXMLDOMText_get_data(nodetext, &str);
2332         ok(r == S_OK, "ret %08x\n", r );
2333         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2334         SysFreeString(str);
2335
2336         /* Confirm XML text is good */
2337         r = IXMLDOMText_get_xml(nodetext, &str);
2338         ok(r == S_OK, "ret %08x\n", r );
2339         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2340         SysFreeString(str);
2341
2342         /* Confirm we get the put_data Text back */
2343         r = IXMLDOMText_get_text(nodetext, &str);
2344         ok(r == S_OK, "ret %08x\n", r );
2345         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2346         SysFreeString(str);
2347
2348         /* test substringData */
2349         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2350         ok(r == E_INVALIDARG, "ret %08x\n", r );
2351
2352         /* test substringData - Invalid offset */
2353         str = (BSTR)&szElement;
2354         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2355         ok(r == E_INVALIDARG, "ret %08x\n", r );
2356         ok( str == NULL, "incorrect string\n");
2357
2358         /* test substringData - Invalid offset */
2359         str = (BSTR)&szElement;
2360         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2361         ok(r == S_FALSE, "ret %08x\n", r );
2362         ok( str == NULL, "incorrect string\n");
2363
2364         /* test substringData - Invalid size */
2365         str = (BSTR)&szElement;
2366         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2367         ok(r == E_INVALIDARG, "ret %08x\n", r );
2368         ok( str == NULL, "incorrect string\n");
2369
2370         /* test substringData - Invalid size */
2371         str = (BSTR)&szElement;
2372         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2373         ok(r == S_FALSE, "ret %08x\n", r );
2374         ok( str == NULL, "incorrect string\n");
2375
2376         /* test substringData - Start of string */
2377         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2378         ok(r == S_OK, "ret %08x\n", r );
2379         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2380         SysFreeString(str);
2381
2382         /* test substringData - Middle of string */
2383         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2384         ok(r == S_OK, "ret %08x\n", r );
2385         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2386         SysFreeString(str);
2387
2388         /* test substringData - End of string */
2389         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2390         ok(r == S_OK, "ret %08x\n", r );
2391         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2392         SysFreeString(str);
2393
2394         /* test appendData */
2395         r = IXMLDOMText_appendData(nodetext, NULL);
2396         ok(r == S_OK, "ret %08x\n", r );
2397
2398         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2399         ok(r == S_OK, "ret %08x\n", r );
2400
2401         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2402         ok(r == S_OK, "ret %08x\n", r );
2403
2404         r = IXMLDOMText_get_text(nodetext, &str);
2405         ok(r == S_OK, "ret %08x\n", r );
2406         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2407         SysFreeString(str);
2408
2409         /* test insertData */
2410         str = SysAllocStringLen(NULL, 0);
2411         r = IXMLDOMText_insertData(nodetext, -1, str);
2412         ok(r == S_OK, "ret %08x\n", r );
2413
2414         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2415         ok(r == S_OK, "ret %08x\n", r );
2416
2417         r = IXMLDOMText_insertData(nodetext, 1000, str);
2418         ok(r == S_OK, "ret %08x\n", r );
2419
2420         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2421         ok(r == S_OK, "ret %08x\n", r );
2422
2423         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2424         ok(r == S_OK, "ret %08x\n", r );
2425
2426         r = IXMLDOMText_insertData(nodetext, 0, str);
2427         ok(r == S_OK, "ret %08x\n", r );
2428         SysFreeString(str);
2429
2430         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2431         ok(r == E_INVALIDARG, "ret %08x\n", r );
2432
2433         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2434         ok(r == E_INVALIDARG, "ret %08x\n", r );
2435
2436         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2437         ok(r == S_OK, "ret %08x\n", r );
2438
2439         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2440         ok(r == S_OK, "ret %08x\n", r );
2441
2442         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2443         ok(r == S_OK, "ret %08x\n", r );
2444
2445         r = IXMLDOMText_get_text(nodetext, &str);
2446         ok(r == S_OK, "ret %08x\n", r );
2447         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2448         SysFreeString(str);
2449
2450         /* delete data */
2451         /* invalid arguments */
2452         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2453         ok(r == E_INVALIDARG, "ret %08x\n", r );
2454
2455         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2456         ok(r == S_OK, "ret %08x\n", r );
2457
2458         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2459         ok(r == E_INVALIDARG, "ret %08x\n", r );
2460
2461         r = IXMLDOMText_get_length(nodetext, &nLength);
2462         ok(r == S_OK, "ret %08x\n", r );
2463         ok(nLength == 43, "expected 43 got %d\n", nLength);
2464
2465         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2466         ok(r == S_OK, "ret %08x\n", r );
2467
2468         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2469         ok(r == E_INVALIDARG, "ret %08x\n", r );
2470
2471         /* delete from start */
2472         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2473         ok(r == S_OK, "ret %08x\n", r );
2474
2475         r = IXMLDOMText_get_length(nodetext, &nLength);
2476         ok(r == S_OK, "ret %08x\n", r );
2477         ok(nLength == 38, "expected 38 got %d\n", nLength);
2478
2479         r = IXMLDOMText_get_text(nodetext, &str);
2480         ok(r == S_OK, "ret %08x\n", r );
2481         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2482         SysFreeString(str);
2483
2484         /* delete from end */
2485         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2486         ok(r == S_OK, "ret %08x\n", r );
2487
2488         r = IXMLDOMText_get_length(nodetext, &nLength);
2489         ok(r == S_OK, "ret %08x\n", r );
2490         ok(nLength == 35, "expected 35 got %d\n", nLength);
2491
2492         r = IXMLDOMText_get_text(nodetext, &str);
2493         ok(r == S_OK, "ret %08x\n", r );
2494         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2495         SysFreeString(str);
2496
2497         /* delete from inside */
2498         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2499         ok(r == S_OK, "ret %08x\n", r );
2500
2501         r = IXMLDOMText_get_length(nodetext, &nLength);
2502         ok(r == S_OK, "ret %08x\n", r );
2503         ok(nLength == 2, "expected 2 got %d\n", nLength);
2504
2505         r = IXMLDOMText_get_text(nodetext, &str);
2506         ok(r == S_OK, "ret %08x\n", r );
2507         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2508         SysFreeString(str);
2509
2510         /* delete whole data ... */
2511         r = IXMLDOMText_get_length(nodetext, &nLength);
2512         ok(r == S_OK, "ret %08x\n", r );
2513
2514         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2515         ok(r == S_OK, "ret %08x\n", r );
2516         /* ... and try again with empty string */
2517         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2518         ok(r == S_OK, "ret %08x\n", r );
2519
2520         /* test put_data */
2521         V_VT(&var) = VT_BSTR;
2522         V_BSTR(&var) = SysAllocString(szstr1);
2523         r = IXMLDOMText_put_nodeValue(nodetext, var);
2524         ok(r == S_OK, "ret %08x\n", r );
2525         VariantClear(&var);
2526
2527         r = IXMLDOMText_get_text(nodetext, &str);
2528         ok(r == S_OK, "ret %08x\n", r );
2529         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2530         SysFreeString(str);
2531
2532         /* test put_data */
2533         V_VT(&var) = VT_I4;
2534         V_I4(&var) = 99;
2535         r = IXMLDOMText_put_nodeValue(nodetext, var);
2536         ok(r == S_OK, "ret %08x\n", r );
2537         VariantClear(&var);
2538
2539         r = IXMLDOMText_get_text(nodetext, &str);
2540         ok(r == S_OK, "ret %08x\n", r );
2541         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2542         SysFreeString(str);
2543
2544         /* ::replaceData() */
2545         V_VT(&var) = VT_BSTR;
2546         V_BSTR(&var) = SysAllocString(szstr1);
2547         r = IXMLDOMText_put_nodeValue(nodetext, var);
2548         ok(r == S_OK, "ret %08x\n", r );
2549         VariantClear(&var);
2550
2551         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2552         ok(r == E_INVALIDARG, "ret %08x\n", r );
2553         r = IXMLDOMText_get_text(nodetext, &str);
2554         ok(r == S_OK, "ret %08x\n", r );
2555         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2556         SysFreeString(str);
2557
2558         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2559         ok(r == S_OK, "ret %08x\n", r );
2560         r = IXMLDOMText_get_text(nodetext, &str);
2561         ok(r == S_OK, "ret %08x\n", r );
2562         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2563         SysFreeString(str);
2564
2565         /* NULL pointer means delete */
2566         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2567         ok(r == S_OK, "ret %08x\n", r );
2568         r = IXMLDOMText_get_text(nodetext, &str);
2569         ok(r == S_OK, "ret %08x\n", r );
2570         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2571         SysFreeString(str);
2572
2573         /* empty string means delete */
2574         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2575         ok(r == S_OK, "ret %08x\n", r );
2576         r = IXMLDOMText_get_text(nodetext, &str);
2577         ok(r == S_OK, "ret %08x\n", r );
2578         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2579         SysFreeString(str);
2580
2581         /* zero count means insert */
2582         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2583         ok(r == S_OK, "ret %08x\n", r );
2584         r = IXMLDOMText_get_text(nodetext, &str);
2585         ok(r == S_OK, "ret %08x\n", r );
2586         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2587         SysFreeString(str);
2588
2589         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2590         ok(r == S_OK, "ret %08x\n", r );
2591
2592         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2593         ok(r == S_OK, "ret %08x\n", r );
2594         r = IXMLDOMText_get_text(nodetext, &str);
2595         ok(r == S_OK, "ret %08x\n", r );
2596         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2597         SysFreeString(str);
2598
2599         /* nonempty string, count greater than its length */
2600         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2601         ok(r == S_OK, "ret %08x\n", r );
2602         r = IXMLDOMText_get_text(nodetext, &str);
2603         ok(r == S_OK, "ret %08x\n", r );
2604         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2605         SysFreeString(str);
2606
2607         /* nonempty string, count less than its length */
2608         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2609         ok(r == S_OK, "ret %08x\n", r );
2610         r = IXMLDOMText_get_text(nodetext, &str);
2611         ok(r == S_OK, "ret %08x\n", r );
2612         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2613         SysFreeString(str);
2614
2615         IXMLDOMText_Release( nodetext );
2616     }
2617
2618     /* test Create Comment */
2619     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2620     ok( r == E_INVALIDARG, "returns %08x\n", r );
2621     node_comment = (IXMLDOMComment*)0x1;
2622
2623     /* empty comment */
2624     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2625     ok( r == S_OK, "returns %08x\n", r );
2626     str = (BSTR)0x1;
2627     r = IXMLDOMComment_get_data(node_comment, &str);
2628     ok( r == S_OK, "returns %08x\n", r );
2629     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2630     IXMLDOMComment_Release(node_comment);
2631     SysFreeString(str);
2632
2633     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2634     ok( r == S_OK, "returns %08x\n", r );
2635     str = (BSTR)0x1;
2636     r = IXMLDOMComment_get_data(node_comment, &str);
2637     ok( r == S_OK, "returns %08x\n", r );
2638     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2639     IXMLDOMComment_Release(node_comment);
2640     SysFreeString(str);
2641
2642     str = SysAllocString(szComment);
2643     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2644     SysFreeString(str);
2645     ok( r == S_OK, "returns %08x\n", r );
2646     if(node_comment)
2647     {
2648         /* Last Child Checks */
2649         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2650         ok(r == E_INVALIDARG, "ret %08x\n", r );
2651
2652         nodeChild = (IXMLDOMNode*)0x1;
2653         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2654         ok(r == S_FALSE, "ret %08x\n", r );
2655         ok(nodeChild == NULL, "pLastChild not NULL\n");
2656
2657         /* baseName */
2658         str = (BSTR)0xdeadbeef;
2659         r = IXMLDOMComment_get_baseName(node_comment, &str);
2660         ok(r == S_FALSE, "ret %08x\n", r );
2661         ok(str == NULL, "Expected NULL\n");
2662
2663         IXMLDOMComment_Release( node_comment );
2664     }
2665
2666     /* test Create Attribute */
2667     str = SysAllocString(szAttribute);
2668     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2669     ok( r == E_INVALIDARG, "returns %08x\n", r );
2670     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2671     ok( r == S_OK, "returns %08x\n", r );
2672     IXMLDOMText_Release( node_attr);
2673     SysFreeString(str);
2674
2675     /* test Processing Instruction */
2676     str = SysAllocStringLen(NULL, 0);
2677     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2678     ok( r == E_INVALIDARG, "returns %08x\n", r );
2679     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2680     ok( r == E_FAIL, "returns %08x\n", r );
2681     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2682     ok( r == E_FAIL, "returns %08x\n", r );
2683     SysFreeString(str);
2684
2685     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2686     ok( r == S_OK, "returns %08x\n", r );
2687     if(nodePI)
2688     {
2689         /* Last Child Checks */
2690         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2691         ok(r == E_INVALIDARG, "ret %08x\n", r );
2692
2693         nodeChild = (IXMLDOMNode*)0x1;
2694         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2695         ok(r == S_FALSE, "ret %08x\n", r );
2696         ok(nodeChild == NULL, "nodeChild not NULL\n");
2697
2698         /* test nodeName */
2699         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2700         ok(r == S_OK, "ret %08x\n", r );
2701         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2702         SysFreeString(str);
2703
2704         /* test baseName */
2705         str = (BSTR)0x1;
2706         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2707         ok(r == S_OK, "ret %08x\n", r );
2708         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2709         SysFreeString(str);
2710
2711         /* test Target */
2712         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2713         ok(r == S_OK, "ret %08x\n", r );
2714         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2715         SysFreeString(str);
2716
2717         /* test get_data */
2718         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2719         ok(r == S_OK, "ret %08x\n", r );
2720         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2721         SysFreeString(str);
2722
2723         /* test put_data */
2724         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2725         ok(r == E_FAIL, "ret %08x\n", r );
2726
2727         /* test put_data */
2728         V_VT(&var) = VT_BSTR;
2729         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2730         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2731         ok(r == E_FAIL, "ret %08x\n", r );
2732         VariantClear(&var);
2733
2734         /* test get nodeName */
2735         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2736         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2737         ok(r == S_OK, "ret %08x\n", r );
2738         SysFreeString(str);
2739
2740         IXMLDOMProcessingInstruction_Release(nodePI);
2741     }
2742
2743     ref = IXMLDOMDocument_Release( doc );
2744     ok( ref == 0, "got %d\n", ref);
2745
2746     free_bstrs();
2747 }
2748
2749 static void test_persiststreaminit(void)
2750 {
2751     IXMLDOMDocument *doc;
2752     IPersistStreamInit *streaminit;
2753     HRESULT hr;
2754
2755     doc = create_document(&IID_IXMLDOMDocument);
2756     if (!doc) return;
2757
2758     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2759     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2760
2761     hr = IPersistStreamInit_InitNew(streaminit);
2762     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2763
2764     IXMLDOMDocument_Release(doc);
2765 }
2766
2767 static void test_domnode( void )
2768 {
2769     HRESULT r;
2770     IXMLDOMDocument *doc, *owner = NULL;
2771     IXMLDOMElement *element = NULL;
2772     IXMLDOMNamedNodeMap *map = NULL;
2773     IXMLDOMNode *node = NULL, *next = NULL;
2774     IXMLDOMNodeList *list = NULL;
2775     IXMLDOMAttribute *attr = NULL;
2776     DOMNodeType type = NODE_INVALID;
2777     VARIANT_BOOL b;
2778     BSTR str;
2779     VARIANT var;
2780     LONG count;
2781
2782     doc = create_document(&IID_IXMLDOMDocument);
2783     if (!doc) return;
2784
2785     b = FALSE;
2786     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2787     ok( r == S_OK, "loadXML failed\n");
2788     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2789
2790     EXPECT_CHILDREN(doc);
2791
2792     r = IXMLDOMDocument_get_documentElement( doc, &element );
2793     ok( r == S_OK, "should be a document element\n");
2794     ok( element != NULL, "should be an element\n");
2795
2796     VariantInit(&var);
2797     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2798
2799     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2800     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2801
2802     r = IXMLDOMNode_get_nodeValue( doc, &var );
2803     ok( r == S_FALSE, "nextNode returned wrong code\n");
2804     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2805     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2806
2807     if (element)
2808     {
2809         owner = NULL;
2810         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2811         ok( r == S_OK, "get_ownerDocument return code\n");
2812         ok( owner != doc, "get_ownerDocument return\n");
2813         IXMLDOMDocument_Release(owner);
2814
2815         type = NODE_INVALID;
2816         r = IXMLDOMNode_get_nodeType( element, &type);
2817         ok( r == S_OK, "got %08x\n", r);
2818         ok( type == NODE_ELEMENT, "node not an element\n");
2819
2820         str = NULL;
2821         r = IXMLDOMNode_get_baseName( element, &str );
2822         ok( r == S_OK, "get_baseName returned wrong code\n");
2823         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2824         SysFreeString(str);
2825
2826         /* check if nodename is correct */
2827         r = IXMLDOMElement_get_nodeName( element, NULL );
2828         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2829
2830         /* content doesn't matter here */
2831         str = NULL;
2832         r = IXMLDOMElement_get_nodeName( element, &str );
2833         ok ( r == S_OK, "get_nodeName wrong code\n");
2834         ok ( str != NULL, "str is null\n");
2835         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2836         SysFreeString( str );
2837
2838         str = SysAllocString( nonexistent_fileW );
2839         V_VT(&var) = VT_I4;
2840         V_I4(&var) = 0x1234;
2841         r = IXMLDOMElement_getAttribute( element, str, &var );
2842         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2843         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2844         VariantClear(&var);
2845
2846         str = SysAllocString( szdl );   
2847         V_VT(&var) = VT_I4;
2848         V_I4(&var) = 0x1234;
2849         r = IXMLDOMElement_getAttribute( element, str, &var );
2850         ok( r == S_OK, "getAttribute ret %08x\n", r );
2851         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2852         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2853         VariantClear( &var );
2854
2855         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2856         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2857
2858         r = IXMLDOMElement_getAttribute( element, str, NULL );
2859         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2860
2861         attr = NULL;
2862         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2863         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2864         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2865         if (attr)
2866         {
2867             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2868             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2869
2870             /* attribute doesn't have a parent in msxml interpretation */
2871             node = (IXMLDOMNode*)0xdeadbeef;
2872             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2873             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2874             ok( node == NULL, "Expected NULL, got %p\n", node );
2875
2876             IXMLDOMAttribute_Release(attr);
2877         }
2878
2879         SysFreeString( str );
2880
2881         r = IXMLDOMElement_get_attributes( element, &map );
2882         ok( r == S_OK, "get_attributes returned wrong code\n");
2883         ok( map != NULL, "should be attributes\n");
2884
2885         EXPECT_CHILDREN(element);
2886     }
2887     else
2888         ok( FALSE, "no element\n");
2889
2890     if (map)
2891     {
2892         str = SysAllocString( szdl );
2893         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2894         ok( r == S_OK, "getNamedItem returned wrong code\n");
2895         ok( node != NULL, "should be attributes\n");
2896         IXMLDOMNode_Release(node);
2897         SysFreeString( str );
2898
2899         str = SysAllocString( szdl );
2900         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2901         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2902         SysFreeString( str );
2903
2904         /* something that isn't in complete4A */
2905         str = SysAllocString( szOpen );
2906         node = (IXMLDOMNode *) 1;
2907         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2908         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2909         ok( node == NULL, "getNamedItem should have returned NULL\n");
2910         SysFreeString( str );
2911
2912         /* test indexed access of attributes */
2913         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2914         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2915
2916         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2917         ok ( r == S_OK, "get_length wrong code\n");
2918         ok ( count == 1, "get_length != 1\n");
2919
2920         node = NULL;
2921         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2922         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2923         ok ( node == NULL, "there is no node\n");
2924
2925         node = NULL;
2926         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2927         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2928         ok ( node == NULL, "there is no attribute\n");
2929
2930         node = NULL;
2931         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2932         ok ( r == S_OK, "get_item (0) wrong code\n");
2933         ok ( node != NULL, "should be attribute\n");
2934
2935         r = IXMLDOMNode_get_nodeName( node, NULL );
2936         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2937
2938         /* content doesn't matter here */
2939         str = NULL;
2940         r = IXMLDOMNode_get_nodeName( node, &str );
2941         ok ( r == S_OK, "get_nodeName wrong code\n");
2942         ok ( str != NULL, "str is null\n");
2943         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2944         SysFreeString( str );
2945         IXMLDOMNode_Release( node );
2946
2947         /* test sequential access of attributes */
2948         node = NULL;
2949         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2950         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2951         ok ( node != NULL, "nextNode, should be attribute\n");
2952         IXMLDOMNode_Release( node );
2953
2954         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2955         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2956         ok ( node == NULL, "nextNode, there is no attribute\n");
2957
2958         r = IXMLDOMNamedNodeMap_reset( map );
2959         ok ( r == S_OK, "reset should return S_OK\n");
2960
2961         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2962         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2963         ok ( node != NULL, "nextNode, should be attribute\n");
2964     }
2965     else
2966         ok( FALSE, "no map\n");
2967
2968     if (node)
2969     {
2970         type = NODE_INVALID;
2971         r = IXMLDOMNode_get_nodeType( node, &type);
2972         ok( r == S_OK, "getNamedItem returned wrong code\n");
2973         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2974
2975         str = NULL;
2976         r = IXMLDOMNode_get_baseName( node, NULL );
2977         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2978
2979         str = NULL;
2980         r = IXMLDOMNode_get_baseName( node, &str );
2981         ok( r == S_OK, "get_baseName returned wrong code\n");
2982         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2983         SysFreeString( str );
2984
2985         r = IXMLDOMNode_get_childNodes( node, NULL );
2986         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2987
2988         r = IXMLDOMNode_get_childNodes( node, &list );
2989         ok( r == S_OK, "get_childNodes returned wrong code\n");
2990
2991         if (list)
2992         {
2993             r = IXMLDOMNodeList_nextNode( list, &next );
2994             ok( r == S_OK, "nextNode returned wrong code\n");
2995         }
2996         else
2997             ok( FALSE, "no childlist\n");
2998
2999         if (next)
3000         {
3001             EXPECT_NO_CHILDREN(next);
3002
3003             type = NODE_INVALID;
3004             r = IXMLDOMNode_get_nodeType( next, &type);
3005             ok( r == S_OK, "getNamedItem returned wrong code\n");
3006             ok( type == NODE_TEXT, "node not text\n");
3007
3008             str = (BSTR) 1;
3009             r = IXMLDOMNode_get_baseName( next, &str );
3010             ok( r == S_FALSE, "get_baseName returned wrong code\n");
3011             ok( str == NULL, "basename was wrong\n");
3012             SysFreeString(str);
3013         }
3014         else
3015             ok( FALSE, "no next\n");
3016
3017         if (next)
3018             IXMLDOMNode_Release( next );
3019         next = NULL;
3020         if (list)
3021             IXMLDOMNodeList_Release( list );
3022         list = NULL;
3023         if (node)
3024             IXMLDOMNode_Release( node );
3025     }
3026     else
3027         ok( FALSE, "no node\n");
3028     node = NULL;
3029
3030     if (map)
3031         IXMLDOMNamedNodeMap_Release( map );
3032
3033     /* now traverse the tree from the root element */
3034     if (element)
3035     {
3036         r = IXMLDOMNode_get_childNodes( element, &list );
3037         ok( r == S_OK, "get_childNodes returned wrong code\n");
3038
3039         /* using get_item for child list doesn't advance the position */
3040         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3041         expect_node(node, "E2.E2.D1");
3042         IXMLDOMNode_Release(node);
3043         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3044         expect_node(node, "E1.E2.D1");
3045         IXMLDOMNode_Release(node);
3046         ole_check(IXMLDOMNodeList_reset(list));
3047
3048         IXMLDOMNodeList_AddRef(list);
3049         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3050         ole_check(IXMLDOMNodeList_reset(list));
3051
3052         node = (void*)0xdeadbeef;
3053         str = SysAllocString(szdl);
3054         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3055         SysFreeString(str);
3056         ok( r == S_FALSE, "ret %08x\n", r );
3057         ok( node == NULL, "node %p\n", node );
3058
3059         str = SysAllocString(szbs);
3060         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3061         SysFreeString(str);
3062         ok( r == S_OK, "ret %08x\n", r );
3063         r = IXMLDOMNode_Release( node );
3064         ok( r == 0, "ret %08x\n", r );
3065     }
3066     else
3067         ok( FALSE, "no element\n");
3068
3069     if (list)
3070     {
3071         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3072         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3073
3074         r = IXMLDOMNodeList_get_length(list, NULL);
3075         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3076
3077         r = IXMLDOMNodeList_get_length( list, &count );
3078         ok( r == S_OK, "get_length returns %08x\n", r );
3079         ok( count == 4, "get_length got %d\n", count );
3080
3081         r = IXMLDOMNodeList_nextNode(list, NULL);
3082         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3083
3084         r = IXMLDOMNodeList_nextNode( list, &node );
3085         ok( r == S_OK, "nextNode returned wrong code\n");
3086     }
3087     else
3088         ok( FALSE, "no list\n");
3089
3090     if (node)
3091     {
3092         type = NODE_INVALID;
3093         r = IXMLDOMNode_get_nodeType( node, &type);
3094         ok( r == S_OK, "getNamedItem returned wrong code\n");
3095         ok( type == NODE_ELEMENT, "node not text\n");
3096
3097         r = IXMLDOMNode_hasChildNodes( node, NULL );
3098         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3099
3100         EXPECT_CHILDREN(node);
3101
3102         str = NULL;
3103         r = IXMLDOMNode_get_baseName( node, &str );
3104         ok( r == S_OK, "get_baseName returned wrong code\n");
3105         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3106         SysFreeString(str);
3107     }
3108     else
3109         ok( FALSE, "no node\n");
3110
3111     if (node)
3112         IXMLDOMNode_Release( node );
3113     if (list)
3114         IXMLDOMNodeList_Release( list );
3115     if (element)
3116         IXMLDOMElement_Release( element );
3117
3118     b = FALSE;
3119     str = SysAllocString( szComplete5 );
3120     r = IXMLDOMDocument_loadXML( doc, str, &b );
3121     ok( r == S_OK, "loadXML failed\n");
3122     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3123     SysFreeString( str );
3124
3125     EXPECT_CHILDREN(doc);
3126
3127     r = IXMLDOMDocument_get_documentElement( doc, &element );
3128     ok( r == S_OK, "should be a document element\n");
3129     ok( element != NULL, "should be an element\n");
3130
3131     if (element)
3132     {
3133         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3134         BSTR tag = NULL;
3135
3136         /* check if the tag is correct */
3137         r = IXMLDOMElement_get_tagName( element, &tag );
3138         ok( r == S_OK, "couldn't get tag name\n");
3139         ok( tag != NULL, "tag was null\n");
3140         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3141         SysFreeString( tag );
3142     }
3143
3144     if (element)
3145         IXMLDOMElement_Release( element );
3146     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3147
3148     free_bstrs();
3149 }
3150
3151 typedef struct {
3152     DOMNodeType type;
3153     REFIID iid;
3154 } refcount_test_t;
3155
3156 static const refcount_test_t refcount_test[] = {
3157     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3158     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3159     { NODE_TEXT,                   &IID_IXMLDOMText },
3160     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3161     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3162     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3163     { NODE_COMMENT,                &IID_IXMLDOMComment },
3164     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3165     { NODE_INVALID,                &IID_NULL }
3166 };
3167
3168 static void test_refs(void)
3169 {
3170     IXMLDOMImplementation *impl, *impl2;
3171     IXMLDOMElement *element, *elem2;
3172     IXMLDOMNodeList *node_list = NULL;
3173     IXMLDOMNode *node, *node2, *node3;
3174     const refcount_test_t *ptr;
3175     IXMLDOMDocument *doc;
3176     IUnknown *unk, *unk2;
3177     VARIANT_BOOL b;
3178     HRESULT hr;
3179     LONG ref;
3180
3181     doc = create_document(&IID_IXMLDOMDocument);
3182     if (!doc) return;
3183
3184     ptr = refcount_test;
3185     while (ptr->type != NODE_INVALID)
3186     {
3187         IUnknown *node_typed, *node_typed2;
3188         IDispatchEx *dispex, *dispex2;
3189         IDispatch *disp, *disp2;
3190         VARIANT type;
3191
3192         V_VT(&type) = VT_I1;
3193         V_I1(&type) = ptr->type;
3194
3195         EXPECT_REF(doc, 1);
3196         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3197         EXPECT_HR(hr, S_OK);
3198         EXPECT_REF(doc, 1);
3199         EXPECT_REF(node, 1);
3200
3201         /* try IDispatch and IUnknown from IXMLDOMNode */
3202         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3203         EXPECT_HR(hr, S_OK);
3204         EXPECT_REF(unk, 2);
3205 todo_wine {
3206         EXPECT_REF(node, 1);
3207         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3208 }
3209         EXPECT_REF(unk, 2);
3210         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3211         EXPECT_HR(hr, S_OK);
3212         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3213         EXPECT_REF(unk, 3);
3214         todo_wine EXPECT_REF(disp, 1);
3215
3216         EXPECT_REF(unk, 3);
3217         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3218         EXPECT_HR(hr, S_OK);
3219         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3220         EXPECT_REF(unk, 4);
3221         todo_wine EXPECT_REF(disp2, 1);
3222
3223         IDispatch_Release(disp);
3224         IDispatch_Release(disp2);
3225
3226         /* get IXMLDOMNode from this IUnknown */
3227         EXPECT_REF(unk, 2);
3228         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3229         EXPECT_HR(hr, S_OK);
3230         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3231         EXPECT_REF(unk, 3);
3232         todo_wine EXPECT_REF(node2, 1);
3233
3234         EXPECT_REF(unk, 3);
3235         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3236         EXPECT_HR(hr, S_OK);
3237         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3238         EXPECT_REF(unk, 4);
3239         todo_wine EXPECT_REF(node3, 1);
3240
3241         IXMLDOMNode_Release(node2);
3242         IXMLDOMNode_Release(node3);
3243
3244         /* try IDispatchEx from IUnknown */
3245         EXPECT_REF(unk, 2);
3246         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3247         EXPECT_HR(hr, S_OK);
3248         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3249         EXPECT_REF(unk, 3);
3250         todo_wine EXPECT_REF(dispex, 1);
3251
3252         EXPECT_REF(unk, 3);
3253         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3254         EXPECT_HR(hr, S_OK);
3255         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3256         EXPECT_REF(unk, 4);
3257         todo_wine EXPECT_REF(dispex2, 1);
3258
3259         IDispatch_Release(dispex);
3260         IDispatch_Release(dispex2);
3261
3262         /* try corresponding IXMLDOM* */
3263         EXPECT_REF(unk, 2);
3264         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3265         EXPECT_HR(hr, S_OK);
3266         EXPECT_REF(unk, 3);
3267         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3268         EXPECT_HR(hr, S_OK);
3269         EXPECT_REF(unk, 4);
3270         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3271         IUnknown_Release(node_typed);
3272         IUnknown_Release(node_typed2);
3273
3274         /* try invalid IXMLDOM* */
3275         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3276         EXPECT_HR(hr, E_NOINTERFACE);
3277
3278         IUnknown_Release(unk);
3279
3280         EXPECT_REF(node, 1);
3281         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3282         EXPECT_HR(hr, S_OK);
3283         EXPECT_REF(node, 2);
3284         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3285
3286         EXPECT_REF(node, 2);
3287         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3288         EXPECT_HR(hr, S_OK);
3289         EXPECT_REF(node, 3);
3290 todo_wine {
3291         EXPECT_REF(node_typed, 2);
3292         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3293 }
3294         IUnknown_Release(node_typed);
3295
3296         IXMLDOMNode_Release(node2);
3297         IXMLDOMNode_Release(node);
3298
3299         ptr++;
3300     }
3301
3302     EXPECT_REF(doc, 1);
3303     ref = IXMLDOMDocument_Release(doc);
3304     ok( ref == 0, "ref %d\n", ref);
3305
3306     /* check IUnknown after releasing DOM iface */
3307     doc = create_document(&IID_IXMLDOMDocument);
3308     EXPECT_REF(doc, 1);
3309     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3310     EXPECT_HR(hr, S_OK);
3311 todo_wine {
3312     EXPECT_REF(unk, 3);
3313     EXPECT_REF(doc, 1);
3314 }
3315     IXMLDOMDocument_Release(doc);
3316     EXPECT_REF(unk, 1);
3317     IUnknown_Release(unk);
3318
3319     doc = create_document(&IID_IXMLDOMDocument);
3320     if (!doc) return;
3321
3322     EXPECT_REF(doc, 1);
3323     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3324     EXPECT_HR(hr, S_OK);
3325 todo_wine {
3326     EXPECT_REF(unk, 3);
3327     EXPECT_REF(doc, 1);
3328 }
3329     IUnknown_Release(unk);
3330
3331     /* IXMLDOMImplementation */
3332     EXPECT_REF(doc, 1);
3333     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3334     EXPECT_HR(hr, S_OK);
3335     EXPECT_REF(doc, 1);
3336     EXPECT_REF(impl, 1);
3337     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3338     EXPECT_HR(hr, S_OK);
3339     EXPECT_REF(doc, 1);
3340     EXPECT_REF(impl2, 1);
3341     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3342     IXMLDOMImplementation_Release(impl);
3343     IXMLDOMImplementation_Release(impl2);
3344
3345     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3346     EXPECT_HR(hr, S_OK);
3347     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3348
3349     EXPECT_REF(doc, 1);
3350     IXMLDOMDocument_AddRef( doc );
3351     EXPECT_REF(doc, 2);
3352     IXMLDOMDocument_AddRef( doc );
3353     EXPECT_REF(doc, 3);
3354
3355     IXMLDOMDocument_Release( doc );
3356     IXMLDOMDocument_Release( doc );
3357
3358     EXPECT_REF(doc, 1);
3359     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3360     EXPECT_HR(hr, S_OK);
3361 todo_wine {
3362     EXPECT_REF(unk, 3);
3363     EXPECT_REF(doc, 1);
3364 }
3365     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3366     EXPECT_HR(hr, S_OK);
3367 todo_wine {
3368     EXPECT_REF(doc, 1);
3369     EXPECT_REF(element, 2);
3370 }
3371     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3372     EXPECT_HR(hr, S_OK);
3373
3374 todo_wine {
3375     EXPECT_REF(doc, 1);
3376     EXPECT_REF(element, 2);
3377     EXPECT_REF(elem2, 2);
3378 }
3379     IXMLDOMElement_AddRef(element);
3380     todo_wine EXPECT_REF(element, 3);
3381     IXMLDOMElement_Release(element);
3382
3383     /* get IUnknown from a node doesn't touch node instance refcount */
3384     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3385     EXPECT_HR(hr, S_OK);
3386     EXPECT_REF(element, 2);
3387 todo_wine {
3388     EXPECT_REF(unk, 4);
3389     EXPECT_REF(elem2, 2);
3390 }
3391     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3392     EXPECT_HR(hr, S_OK);
3393 todo_wine {
3394     EXPECT_REF(unk, 5);
3395     EXPECT_REF(unk2, 5);
3396 }
3397     EXPECT_REF(element, 2);
3398     EXPECT_REF(elem2, 2);
3399
3400     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3401
3402     IUnknown_Release(unk);
3403     IUnknown_Release(unk2);
3404
3405     /* IUnknown refcount is not affected by node refcount */
3406     todo_wine EXPECT_REF(unk2, 3);
3407     IXMLDOMElement_AddRef(elem2);
3408     todo_wine EXPECT_REF(unk2, 3);
3409     IXMLDOMElement_Release(elem2);
3410
3411     IXMLDOMElement_Release(elem2);
3412     todo_wine EXPECT_REF(unk2, 2);
3413
3414     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3415     EXPECT_HR(hr, S_OK);
3416
3417     todo_wine EXPECT_REF(element, 2);
3418     EXPECT_REF(node_list, 1);
3419
3420     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3421     EXPECT_HR(hr, S_OK);
3422     EXPECT_REF(node_list, 1);
3423     EXPECT_REF(node, 1);
3424
3425     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3426     EXPECT_HR(hr, S_OK);
3427     EXPECT_REF(node_list, 1);
3428     EXPECT_REF(node2, 1);
3429
3430     ref = IXMLDOMNode_Release( node );
3431     ok( ref == 0, "ref %d\n", ref );
3432     ref = IXMLDOMNode_Release( node2 );
3433     ok( ref == 0, "ref %d\n", ref );
3434
3435     ref = IXMLDOMNodeList_Release( node_list );
3436     ok( ref == 0, "ref %d\n", ref );
3437
3438     ok( node != node2, "node %p node2 %p\n", node, node2 );
3439
3440     ref = IXMLDOMDocument_Release( doc );
3441     todo_wine ok( ref == 0, "ref %d\n", ref );
3442
3443     todo_wine EXPECT_REF(element, 2);
3444
3445     /* IUnknown must be unique however we obtain it */
3446     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3447     EXPECT_HR(hr, S_OK);
3448     EXPECT_REF(element, 2);
3449     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3450     EXPECT_HR(hr, S_OK);
3451     todo_wine EXPECT_REF(element, 2);
3452     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3453     EXPECT_HR(hr, S_OK);
3454     todo_wine EXPECT_REF(element, 2);
3455     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3456     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3457
3458     IUnknown_Release( unk2 );
3459     IUnknown_Release( unk );
3460     IXMLDOMNode_Release( node );
3461     todo_wine EXPECT_REF(element, 2);
3462
3463     IXMLDOMElement_Release( element );
3464
3465     free_bstrs();
3466 }
3467
3468 static void test_create(void)
3469 {
3470     static const WCHAR szOne[] = {'1',0};
3471     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3472     HRESULT r;
3473     VARIANT var;
3474     BSTR str, name;
3475     IXMLDOMDocument *doc;
3476     IXMLDOMElement *element;
3477     IXMLDOMComment *comment;
3478     IXMLDOMText *text;
3479     IXMLDOMCDATASection *cdata;
3480     IXMLDOMNode *root, *node, *child;
3481     IXMLDOMNamedNodeMap *attr_map;
3482     IUnknown *unk;
3483     LONG ref;
3484     LONG num;
3485
3486     doc = create_document(&IID_IXMLDOMDocument);
3487     if (!doc) return;
3488
3489     EXPECT_REF(doc, 1);
3490
3491     /* types not supported for creation */
3492     V_VT(&var) = VT_I1;
3493     V_I1(&var) = NODE_DOCUMENT;
3494     node = (IXMLDOMNode*)0x1;
3495     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3496     ok( r == E_INVALIDARG, "returns %08x\n", r );
3497     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3498
3499     V_VT(&var) = VT_I1;
3500     V_I1(&var) = NODE_DOCUMENT_TYPE;
3501     node = (IXMLDOMNode*)0x1;
3502     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3503     ok( r == E_INVALIDARG, "returns %08x\n", r );
3504     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3505
3506     V_VT(&var) = VT_I1;
3507     V_I1(&var) = NODE_ENTITY;
3508     node = (IXMLDOMNode*)0x1;
3509     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3510     ok( r == E_INVALIDARG, "returns %08x\n", r );
3511     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3512
3513     V_VT(&var) = VT_I1;
3514     V_I1(&var) = NODE_NOTATION;
3515     node = (IXMLDOMNode*)0x1;
3516     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3517     ok( r == E_INVALIDARG, "returns %08x\n", r );
3518     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3519
3520     /* NODE_COMMENT */
3521     V_VT(&var) = VT_I1;
3522     V_I1(&var) = NODE_COMMENT;
3523     node = NULL;
3524     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3525     ok( r == S_OK, "returns %08x\n", r );
3526     ok( node != NULL, "\n");
3527
3528     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3529     ok( r == S_OK, "returns %08x\n", r );
3530     IXMLDOMNode_Release(node);
3531
3532     str = NULL;
3533     r = IXMLDOMComment_get_data(comment, &str);
3534     ok( r == S_OK, "returns %08x\n", r );
3535     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3536     IXMLDOMComment_Release(comment);
3537     SysFreeString(str);
3538
3539     node = (IXMLDOMNode*)0x1;
3540     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3541     ok( r == S_OK, "returns %08x\n", r );
3542
3543     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3544     ok( r == S_OK, "returns %08x\n", r );
3545     IXMLDOMNode_Release(node);
3546
3547     str = NULL;
3548     r = IXMLDOMComment_get_data(comment, &str);
3549     ok( r == S_OK, "returns %08x\n", r );
3550     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3551     IXMLDOMComment_Release(comment);
3552     SysFreeString(str);
3553
3554     node = (IXMLDOMNode*)0x1;
3555     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3556     ok( r == S_OK, "returns %08x\n", r );
3557
3558     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3559     ok( r == S_OK, "returns %08x\n", r );
3560     IXMLDOMNode_Release(node);
3561
3562     str = NULL;
3563     r = IXMLDOMComment_get_data(comment, &str);
3564     ok( r == S_OK, "returns %08x\n", r );
3565     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3566     IXMLDOMComment_Release(comment);
3567     SysFreeString(str);
3568
3569     /* NODE_TEXT */
3570     V_VT(&var) = VT_I1;
3571     V_I1(&var) = NODE_TEXT;
3572     node = NULL;
3573     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3574     ok( r == S_OK, "returns %08x\n", r );
3575     ok( node != NULL, "\n");
3576
3577     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3578     ok( r == S_OK, "returns %08x\n", r );
3579     IXMLDOMNode_Release(node);
3580
3581     str = NULL;
3582     r = IXMLDOMText_get_data(text, &str);
3583     ok( r == S_OK, "returns %08x\n", r );
3584     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3585     IXMLDOMText_Release(text);
3586     SysFreeString(str);
3587
3588     node = (IXMLDOMNode*)0x1;
3589     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3590     ok( r == S_OK, "returns %08x\n", r );
3591
3592     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3593     ok( r == S_OK, "returns %08x\n", r );
3594     IXMLDOMNode_Release(node);
3595
3596     str = NULL;
3597     r = IXMLDOMText_get_data(text, &str);
3598     ok( r == S_OK, "returns %08x\n", r );
3599     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3600     IXMLDOMText_Release(text);
3601     SysFreeString(str);
3602
3603     node = (IXMLDOMNode*)0x1;
3604     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3605     ok( r == S_OK, "returns %08x\n", r );
3606
3607     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3608     ok( r == S_OK, "returns %08x\n", r );
3609     IXMLDOMNode_Release(node);
3610
3611     str = NULL;
3612     r = IXMLDOMText_get_data(text, &str);
3613     ok( r == S_OK, "returns %08x\n", r );
3614     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3615     IXMLDOMText_Release(text);
3616     SysFreeString(str);
3617
3618     /* NODE_CDATA_SECTION */
3619     V_VT(&var) = VT_I1;
3620     V_I1(&var) = NODE_CDATA_SECTION;
3621     node = NULL;
3622     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3623     ok( r == S_OK, "returns %08x\n", r );
3624     ok( node != NULL, "\n");
3625
3626     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3627     ok( r == S_OK, "returns %08x\n", r );
3628     IXMLDOMNode_Release(node);
3629
3630     str = NULL;
3631     r = IXMLDOMCDATASection_get_data(cdata, &str);
3632     ok( r == S_OK, "returns %08x\n", r );
3633     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3634     IXMLDOMCDATASection_Release(cdata);
3635     SysFreeString(str);
3636
3637     node = (IXMLDOMNode*)0x1;
3638     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3639     ok( r == S_OK, "returns %08x\n", r );
3640
3641     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3642     ok( r == S_OK, "returns %08x\n", r );
3643     IXMLDOMNode_Release(node);
3644
3645     str = NULL;
3646     r = IXMLDOMCDATASection_get_data(cdata, &str);
3647     ok( r == S_OK, "returns %08x\n", r );
3648     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3649     IXMLDOMCDATASection_Release(cdata);
3650     SysFreeString(str);
3651
3652     node = (IXMLDOMNode*)0x1;
3653     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3654     ok( r == S_OK, "returns %08x\n", r );
3655
3656     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3657     ok( r == S_OK, "returns %08x\n", r );
3658     IXMLDOMNode_Release(node);
3659
3660     str = NULL;
3661     r = IXMLDOMCDATASection_get_data(cdata, &str);
3662     ok( r == S_OK, "returns %08x\n", r );
3663     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3664     IXMLDOMCDATASection_Release(cdata);
3665     SysFreeString(str);
3666
3667     /* NODE_ATTRIBUTE */
3668     V_VT(&var) = VT_I1;
3669     V_I1(&var) = NODE_ATTRIBUTE;
3670     node = (IXMLDOMNode*)0x1;
3671     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3672     ok( r == E_FAIL, "returns %08x\n", r );
3673     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3674
3675     V_VT(&var) = VT_I1;
3676     V_I1(&var) = NODE_ATTRIBUTE;
3677     node = (IXMLDOMNode*)0x1;
3678     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3679     ok( r == E_FAIL, "returns %08x\n", r );
3680     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3681
3682     V_VT(&var) = VT_I1;
3683     V_I1(&var) = NODE_ATTRIBUTE;
3684     str = SysAllocString( szlc );
3685     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3686     ok( r == S_OK, "returns %08x\n", r );
3687     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3688     SysFreeString(str);
3689
3690     /* a name is required for attribute, try a BSTR with first null wchar */
3691     V_VT(&var) = VT_I1;
3692     V_I1(&var) = NODE_ATTRIBUTE;
3693     str = SysAllocString( szstr1 );
3694     str[0] = 0;
3695     node = (IXMLDOMNode*)0x1;
3696     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3697     ok( r == E_FAIL, "returns %08x\n", r );
3698     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3699     SysFreeString(str);
3700
3701     /* NODE_PROCESSING_INSTRUCTION */
3702     V_VT(&var) = VT_I1;
3703     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3704     node = (IXMLDOMNode*)0x1;
3705     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3706     ok( r == E_FAIL, "returns %08x\n", r );
3707     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3708
3709     V_VT(&var) = VT_I1;
3710     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3711     node = (IXMLDOMNode*)0x1;
3712     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3713     ok( r == E_FAIL, "returns %08x\n", r );
3714     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3715
3716     V_VT(&var) = VT_I1;
3717     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3718     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3719     ok( r == E_INVALIDARG, "returns %08x\n", r );
3720
3721     /* NODE_ENTITY_REFERENCE */
3722     V_VT(&var) = VT_I1;
3723     V_I1(&var) = NODE_ENTITY_REFERENCE;
3724     node = (IXMLDOMNode*)0x1;
3725     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3726     ok( r == E_FAIL, "returns %08x\n", r );
3727     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3728
3729     V_VT(&var) = VT_I1;
3730     V_I1(&var) = NODE_ENTITY_REFERENCE;
3731     node = (IXMLDOMNode*)0x1;
3732     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3733     ok( r == E_FAIL, "returns %08x\n", r );
3734     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3735
3736     /* NODE_ELEMENT */
3737     V_VT(&var) = VT_I1;
3738     V_I1(&var) = NODE_ELEMENT;
3739     node = (IXMLDOMNode*)0x1;
3740     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3741     ok( r == E_FAIL, "returns %08x\n", r );
3742     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3743
3744     V_VT(&var) = VT_I1;
3745     V_I1(&var) = NODE_ELEMENT;
3746     node = (IXMLDOMNode*)0x1;
3747     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3748     ok( r == E_FAIL, "returns %08x\n", r );
3749     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3750
3751     V_VT(&var) = VT_I1;
3752     V_I1(&var) = NODE_ELEMENT;
3753     str = SysAllocString( szlc );
3754     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3755     ok( r == S_OK, "returns %08x\n", r );
3756     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3757
3758     V_VT(&var) = VT_I1;
3759     V_I1(&var) = NODE_ELEMENT;
3760     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3761     ok( r == E_INVALIDARG, "returns %08x\n", r );
3762
3763     V_VT(&var) = VT_R4;
3764     V_R4(&var) = NODE_ELEMENT;
3765     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3766     ok( r == S_OK, "returns %08x\n", r );
3767     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3768
3769     V_VT(&var) = VT_BSTR;
3770     V_BSTR(&var) = SysAllocString( szOne );
3771     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3772     ok( r == S_OK, "returns %08x\n", r );
3773     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3774     VariantClear(&var);
3775
3776     V_VT(&var) = VT_BSTR;
3777     V_BSTR(&var) = SysAllocString( szOneGarbage );
3778     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3779     ok( r == E_INVALIDARG, "returns %08x\n", r );
3780     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3781     VariantClear(&var);
3782
3783     V_VT(&var) = VT_I4;
3784     V_I4(&var) = NODE_ELEMENT;
3785     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3786     ok( r == S_OK, "returns %08x\n", r );
3787
3788     EXPECT_REF(doc, 1);
3789     r = IXMLDOMDocument_appendChild( doc, node, &root );
3790     ok( r == S_OK, "returns %08x\n", r );
3791     ok( node == root, "%p %p\n", node, root );
3792     EXPECT_REF(doc, 1);
3793
3794     EXPECT_REF(node, 2);
3795
3796     ref = IXMLDOMNode_Release( node );
3797     ok(ref == 1, "ref %d\n", ref);
3798     SysFreeString( str );
3799
3800     V_VT(&var) = VT_I4;
3801     V_I4(&var) = NODE_ELEMENT;
3802     str = SysAllocString( szbs );
3803     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3804     ok( r == S_OK, "returns %08x\n", r );
3805     SysFreeString( str );
3806
3807     EXPECT_REF(node, 1);
3808
3809     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3810     ok( r == S_OK, "returns %08x\n", r );
3811
3812     EXPECT_REF(unk, 2);
3813
3814     V_VT(&var) = VT_EMPTY;
3815     child = NULL;
3816     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3817     ok( r == S_OK, "returns %08x\n", r );
3818     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3819
3820     todo_wine EXPECT_REF(unk, 4);
3821
3822     IXMLDOMNode_Release( child );
3823     IUnknown_Release( unk );
3824
3825     V_VT(&var) = VT_NULL;
3826     V_DISPATCH(&var) = (IDispatch*)node;
3827     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3828     ok( r == S_OK, "returns %08x\n", r );
3829     ok( node == child, "%p %p\n", node, child );
3830     IXMLDOMNode_Release( child );
3831
3832     V_VT(&var) = VT_NULL;
3833     V_DISPATCH(&var) = (IDispatch*)node;
3834     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3835     ok( r == S_OK, "returns %08x\n", r );
3836     IXMLDOMNode_Release( node );
3837
3838     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3839     ok( r == S_OK, "returns %08x\n", r );
3840
3841     r = IXMLDOMElement_get_attributes( element, &attr_map );
3842     ok( r == S_OK, "returns %08x\n", r );
3843     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3844     ok( r == S_OK, "returns %08x\n", r );
3845     ok( num == 0, "num %d\n", num );
3846     IXMLDOMNamedNodeMap_Release( attr_map );
3847
3848     V_VT(&var) = VT_BSTR;
3849     V_BSTR(&var) = SysAllocString( szstr1 );
3850     name = SysAllocString( szdl );
3851     r = IXMLDOMElement_setAttribute( element, name, var );
3852     ok( r == S_OK, "returns %08x\n", r );
3853     r = IXMLDOMElement_get_attributes( element, &attr_map );
3854     ok( r == S_OK, "returns %08x\n", r );
3855     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3856     ok( r == S_OK, "returns %08x\n", r );
3857     ok( num == 1, "num %d\n", num );
3858     IXMLDOMNamedNodeMap_Release( attr_map );
3859     VariantClear(&var);
3860
3861     V_VT(&var) = VT_BSTR;
3862     V_BSTR(&var) = SysAllocString( szstr2 );
3863     r = IXMLDOMElement_setAttribute( element, name, var );
3864     ok( r == S_OK, "returns %08x\n", r );
3865     r = IXMLDOMElement_get_attributes( element, &attr_map );
3866     ok( r == S_OK, "returns %08x\n", r );
3867     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3868     ok( r == S_OK, "returns %08x\n", r );
3869     ok( num == 1, "num %d\n", num );
3870     IXMLDOMNamedNodeMap_Release( attr_map );
3871     VariantClear(&var);
3872     r = IXMLDOMElement_getAttribute( element, name, &var );
3873     ok( r == S_OK, "returns %08x\n", r );
3874     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3875     VariantClear(&var);
3876     SysFreeString(name);
3877
3878     V_VT(&var) = VT_BSTR;
3879     V_BSTR(&var) = SysAllocString( szstr1 );
3880     name = SysAllocString( szlc );
3881     r = IXMLDOMElement_setAttribute( element, name, var );
3882     ok( r == S_OK, "returns %08x\n", r );
3883     r = IXMLDOMElement_get_attributes( element, &attr_map );
3884     ok( r == S_OK, "returns %08x\n", r );
3885     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3886     ok( r == S_OK, "returns %08x\n", r );
3887     ok( num == 2, "num %d\n", num );
3888     IXMLDOMNamedNodeMap_Release( attr_map );
3889     VariantClear(&var);
3890     SysFreeString(name);
3891
3892     V_VT(&var) = VT_I4;
3893     V_I4(&var) = 10;
3894     name = SysAllocString( szbs );
3895     r = IXMLDOMElement_setAttribute( element, name, var );
3896     ok( r == S_OK, "returns %08x\n", r );
3897     VariantClear(&var);
3898     r = IXMLDOMElement_getAttribute( element, name, &var );
3899     ok( r == S_OK, "returns %08x\n", r );
3900     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3901     VariantClear(&var);
3902     SysFreeString(name);
3903
3904     /* Create an Attribute */
3905     V_VT(&var) = VT_I4;
3906     V_I4(&var) = NODE_ATTRIBUTE;
3907     str = SysAllocString( szAttribute );
3908     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3909     ok( r == S_OK, "returns %08x\n", r );
3910     ok( node != NULL, "node was null\n");
3911     SysFreeString(str);
3912
3913     IXMLDOMElement_Release( element );
3914     IXMLDOMNode_Release( root );
3915     IXMLDOMDocument_Release( doc );
3916 }
3917
3918 static void test_getElementsByTagName(void)
3919 {
3920     IXMLDOMNodeList *node_list;
3921     IXMLDOMDocument *doc;
3922     IXMLDOMElement *elem;
3923     WCHAR buff[100];
3924     VARIANT_BOOL b;
3925     HRESULT r;
3926     LONG len;
3927     BSTR str;
3928
3929     doc = create_document(&IID_IXMLDOMDocument);
3930     if (!doc) return;
3931
3932     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3933     ok( r == S_OK, "loadXML failed\n");
3934     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3935
3936     str = SysAllocString( szstar );
3937
3938     /* null arguments cases */
3939     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3940     ok( r == E_INVALIDARG, "ret %08x\n", r );
3941     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3942     ok( r == E_INVALIDARG, "ret %08x\n", r );
3943
3944     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3945     ok( r == S_OK, "ret %08x\n", r );
3946     r = IXMLDOMNodeList_get_length( node_list, &len );
3947     ok( r == S_OK, "ret %08x\n", r );
3948     ok( len == 6, "len %d\n", len );
3949
3950     IXMLDOMNodeList_Release( node_list );
3951     SysFreeString( str );
3952
3953     /* broken query BSTR */
3954     memcpy(&buff[2], szstar, sizeof(szstar));
3955     /* just a big length */
3956     *(DWORD*)buff = 0xf0f0;
3957     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3958     ok( r == S_OK, "ret %08x\n", r );
3959     r = IXMLDOMNodeList_get_length( node_list, &len );
3960     ok( r == S_OK, "ret %08x\n", r );
3961     ok( len == 6, "len %d\n", len );
3962     IXMLDOMNodeList_Release( node_list );
3963
3964     str = SysAllocString( szbs );
3965     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3966     ok( r == S_OK, "ret %08x\n", r );
3967     r = IXMLDOMNodeList_get_length( node_list, &len );
3968     ok( r == S_OK, "ret %08x\n", r );
3969     ok( len == 1, "len %d\n", len );
3970     IXMLDOMNodeList_Release( node_list );
3971     SysFreeString( str );
3972
3973     str = SysAllocString( szdl );
3974     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3975     ok( r == S_OK, "ret %08x\n", r );
3976     r = IXMLDOMNodeList_get_length( node_list, &len );
3977     ok( r == S_OK, "ret %08x\n", r );
3978     ok( len == 0, "len %d\n", len );
3979     IXMLDOMNodeList_Release( node_list );
3980     SysFreeString( str );
3981
3982     str = SysAllocString( szstr1 );
3983     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3984     ok( r == S_OK, "ret %08x\n", r );
3985     r = IXMLDOMNodeList_get_length( node_list, &len );
3986     ok( r == S_OK, "ret %08x\n", r );
3987     ok( len == 0, "len %d\n", len );
3988     IXMLDOMNodeList_Release( node_list );
3989     SysFreeString( str );
3990
3991     /* test for element */
3992     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3993     ok( r == S_OK, "ret %08x\n", r );
3994
3995     str = SysAllocString( szstar );
3996
3997     /* null arguments cases */
3998     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3999     ok( r == E_INVALIDARG, "ret %08x\n", r );
4000     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
4001     ok( r == E_INVALIDARG, "ret %08x\n", r );
4002
4003     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
4004     ok( r == S_OK, "ret %08x\n", r );
4005     r = IXMLDOMNodeList_get_length( node_list, &len );
4006     ok( r == S_OK, "ret %08x\n", r );
4007     ok( len == 5, "len %d\n", len );
4008     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
4009     SysFreeString( str );
4010
4011     /* broken query BSTR */
4012     memcpy(&buff[2], szstar, sizeof(szstar));
4013     /* just a big length */
4014     *(DWORD*)buff = 0xf0f0;
4015     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
4016     ok( r == S_OK, "ret %08x\n", r );
4017     r = IXMLDOMNodeList_get_length( node_list, &len );
4018     ok( r == S_OK, "ret %08x\n", r );
4019     ok( len == 5, "len %d\n", len );
4020     IXMLDOMNodeList_Release( node_list );
4021
4022     IXMLDOMElement_Release(elem);
4023
4024     IXMLDOMDocument_Release( doc );
4025
4026     free_bstrs();
4027 }
4028
4029 static void test_get_text(void)
4030 {
4031     HRESULT r;
4032     BSTR str;
4033     VARIANT_BOOL b;
4034     IXMLDOMDocument *doc;
4035     IXMLDOMNode *node, *node2, *node3;
4036     IXMLDOMNode *nodeRoot;
4037     IXMLDOMNodeList *node_list;
4038     IXMLDOMNamedNodeMap *node_map;
4039     LONG len;
4040
4041     doc = create_document(&IID_IXMLDOMDocument);
4042     if (!doc) return;
4043
4044     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4045     ok( r == S_OK, "loadXML failed\n");
4046     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4047
4048     str = SysAllocString( szbs );
4049     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
4050     ok( r == S_OK, "ret %08x\n", r );
4051     SysFreeString(str);
4052
4053     /* Test to get all child node text. */
4054     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
4055     ok( r == S_OK, "ret %08x\n", r );
4056     if(r == S_OK)
4057     {
4058         r = IXMLDOMNode_get_text( nodeRoot, &str );
4059         ok( r == S_OK, "ret %08x\n", r );
4060         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
4061         SysFreeString(str);
4062
4063         IXMLDOMNode_Release(nodeRoot);
4064     }
4065
4066     r = IXMLDOMNodeList_get_length( node_list, NULL );
4067     ok( r == E_INVALIDARG, "ret %08x\n", r );
4068
4069     r = IXMLDOMNodeList_get_length( node_list, &len );
4070     ok( r == S_OK, "ret %08x\n", r );
4071     ok( len == 1, "expect 1 got %d\n", len );
4072
4073     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
4074     ok( r == E_INVALIDARG, "ret %08x\n", r );
4075
4076     r = IXMLDOMNodeList_nextNode( node_list, NULL );
4077     ok( r == E_INVALIDARG, "ret %08x\n", r );
4078
4079     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4080     ok( r == S_OK, "ret %08x\n", r );
4081     IXMLDOMNodeList_Release( node_list );
4082
4083     /* Invalid output parameter*/
4084     r = IXMLDOMNode_get_text( node, NULL );
4085     ok( r == E_INVALIDARG, "ret %08x\n", r );
4086
4087     r = IXMLDOMNode_get_text( node, &str );
4088     ok( r == S_OK, "ret %08x\n", r );
4089     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4090     SysFreeString(str);
4091
4092     r = IXMLDOMNode_get_attributes( node, &node_map );
4093     ok( r == S_OK, "ret %08x\n", r );
4094
4095     str = SysAllocString( szvr );
4096     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4097     ok( r == S_OK, "ret %08x\n", r );
4098     SysFreeString(str);
4099
4100     r = IXMLDOMNode_get_text( node2, &str );
4101     ok( r == S_OK, "ret %08x\n", r );
4102     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4103     SysFreeString(str);
4104
4105     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4106     ok( r == S_OK, "ret %08x\n", r );
4107
4108     r = IXMLDOMNode_get_text( node3, &str );
4109     ok( r == S_OK, "ret %08x\n", r );
4110     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4111     SysFreeString(str);
4112
4113
4114     IXMLDOMNode_Release( node3 );
4115     IXMLDOMNode_Release( node2 );
4116     IXMLDOMNamedNodeMap_Release( node_map );
4117     IXMLDOMNode_Release( node );
4118     IXMLDOMDocument_Release( doc );
4119
4120     free_bstrs();
4121 }
4122
4123 static void test_get_childNodes(void)
4124 {
4125     BSTR str;
4126     VARIANT_BOOL b;
4127     IXMLDOMDocument *doc;
4128     IXMLDOMElement *element;
4129     IXMLDOMNode *node, *node2;
4130     IXMLDOMNodeList *node_list, *node_list2;
4131     HRESULT hr;
4132     LONG len;
4133
4134     doc = create_document(&IID_IXMLDOMDocument);
4135     if (!doc) return;
4136
4137     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4138     EXPECT_HR(hr, S_OK);
4139     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4140
4141     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4142     EXPECT_HR(hr, S_OK);
4143
4144     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4145     EXPECT_HR(hr, S_OK);
4146
4147     hr = IXMLDOMNodeList_get_length( node_list, &len );
4148     EXPECT_HR(hr, S_OK);
4149     ok( len == 4, "len %d\n", len);
4150
4151     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4152     EXPECT_HR(hr, S_OK);
4153
4154     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4155     EXPECT_HR(hr, S_OK);
4156
4157     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4158     EXPECT_HR(hr, S_OK);
4159     ok( len == 0, "len %d\n", len);
4160
4161     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4162     EXPECT_HR(hr, S_FALSE);
4163
4164     IXMLDOMNodeList_Release( node_list2 );
4165     IXMLDOMNode_Release( node );
4166     IXMLDOMNodeList_Release( node_list );
4167     IXMLDOMElement_Release( element );
4168
4169     /* test for children of <?xml ..?> node */
4170     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4171     EXPECT_HR(hr, S_OK);
4172
4173     str = NULL;
4174     hr = IXMLDOMNode_get_nodeName(node, &str);
4175     EXPECT_HR(hr, S_OK);
4176     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4177     SysFreeString(str);
4178
4179     /* it returns empty but valid node list */
4180     node_list = (void*)0xdeadbeef;
4181     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4182     EXPECT_HR(hr, S_OK);
4183
4184     len = -1;
4185     hr = IXMLDOMNodeList_get_length(node_list, &len);
4186     EXPECT_HR(hr, S_OK);
4187     ok(len == 0, "got %d\n", len);
4188
4189     IXMLDOMNodeList_Release( node_list );
4190     IXMLDOMNode_Release(node);
4191
4192     IXMLDOMDocument_Release( doc );
4193     free_bstrs();
4194 }
4195
4196 static void test_get_firstChild(void)
4197 {
4198     static WCHAR xmlW[] = {'x','m','l',0};
4199     IXMLDOMDocument *doc;
4200     IXMLDOMNode *node;
4201     VARIANT_BOOL b;
4202     HRESULT r;
4203     BSTR str;
4204
4205     doc = create_document(&IID_IXMLDOMDocument);
4206     if (!doc) return;
4207
4208     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4209     ok( r == S_OK, "loadXML failed\n");
4210     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4211
4212     r = IXMLDOMDocument_get_firstChild( doc, &node );
4213     ok( r == S_OK, "ret %08x\n", r);
4214
4215     r = IXMLDOMNode_get_nodeName( node, &str );
4216     ok( r == S_OK, "ret %08x\n", r);
4217
4218     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4219
4220     SysFreeString(str);
4221     IXMLDOMNode_Release( node );
4222     IXMLDOMDocument_Release( doc );
4223
4224     free_bstrs();
4225 }
4226
4227 static void test_get_lastChild(void)
4228 {
4229     static WCHAR lcW[] = {'l','c',0};
4230     static WCHAR foW[] = {'f','o',0};
4231     IXMLDOMDocument *doc;
4232     IXMLDOMNode *node, *child;
4233     VARIANT_BOOL b;
4234     HRESULT r;
4235     BSTR str;
4236
4237     doc = create_document(&IID_IXMLDOMDocument);
4238     if (!doc) return;
4239
4240     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4241     ok( r == S_OK, "loadXML failed\n");
4242     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4243
4244     r = IXMLDOMDocument_get_lastChild( doc, &node );
4245     ok( r == S_OK, "ret %08x\n", r);
4246
4247     r = IXMLDOMNode_get_nodeName( node, &str );
4248     ok( r == S_OK, "ret %08x\n", r);
4249
4250     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4251     SysFreeString(str);
4252
4253     r = IXMLDOMNode_get_lastChild( node, &child );
4254     ok( r == S_OK, "ret %08x\n", r);
4255
4256     r = IXMLDOMNode_get_nodeName( child, &str );
4257     ok( r == S_OK, "ret %08x\n", r);
4258
4259     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4260     SysFreeString(str);
4261
4262     IXMLDOMNode_Release( child );
4263     IXMLDOMNode_Release( node );
4264     IXMLDOMDocument_Release( doc );
4265
4266     free_bstrs();
4267 }
4268
4269 static void test_removeChild(void)
4270 {
4271     HRESULT r;
4272     VARIANT_BOOL b;
4273     IXMLDOMDocument *doc;
4274     IXMLDOMElement *element, *lc_element;
4275     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4276     IXMLDOMNodeList *root_list, *fo_list;
4277
4278     doc = create_document(&IID_IXMLDOMDocument);
4279     if (!doc) return;
4280
4281     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4282     ok( r == S_OK, "loadXML failed\n");
4283     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4284
4285     r = IXMLDOMDocument_get_documentElement( doc, &element );
4286     ok( r == S_OK, "ret %08x\n", r);
4287     todo_wine EXPECT_REF(element, 2);
4288
4289     r = IXMLDOMElement_get_childNodes( element, &root_list );
4290     ok( r == S_OK, "ret %08x\n", r);
4291     EXPECT_REF(root_list, 1);
4292
4293     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4294     ok( r == S_OK, "ret %08x\n", r);
4295     EXPECT_REF(fo_node, 1);
4296
4297     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4298     ok( r == S_OK, "ret %08x\n", r);
4299     EXPECT_REF(fo_list, 1);
4300
4301     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4302     ok( r == S_OK, "ret %08x\n", r);
4303     EXPECT_REF(ba_node, 1);
4304
4305     /* invalid parameter: NULL ptr */
4306     removed_node = (void*)0xdeadbeef;
4307     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4308     ok( r == E_INVALIDARG, "ret %08x\n", r );
4309     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4310
4311     /* ba_node is a descendant of element, but not a direct child. */
4312     removed_node = (void*)0xdeadbeef;
4313     EXPECT_REF(ba_node, 1);
4314     EXPECT_CHILDREN(fo_node);
4315     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4316     ok( r == E_INVALIDARG, "ret %08x\n", r );
4317     ok( removed_node == NULL, "%p\n", removed_node );
4318     EXPECT_REF(ba_node, 1);
4319     EXPECT_CHILDREN(fo_node);
4320
4321     EXPECT_REF(ba_node, 1);
4322     EXPECT_REF(fo_node, 1);
4323     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4324     ok( r == S_OK, "ret %08x\n", r);
4325     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4326     EXPECT_REF(fo_node, 2);
4327     EXPECT_REF(ba_node, 1);
4328
4329     /* try removing already removed child */
4330     temp_node = (void*)0xdeadbeef;
4331     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4332     ok( r == E_INVALIDARG, "ret %08x\n", r);
4333     ok( temp_node == NULL, "%p\n", temp_node );
4334     IXMLDOMNode_Release( fo_node );
4335
4336     /* the removed node has no parent anymore */
4337     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4338     ok( r == S_FALSE, "ret %08x\n", r);
4339     ok( temp_node == NULL, "%p\n", temp_node );
4340
4341     IXMLDOMNode_Release( removed_node );
4342     IXMLDOMNode_Release( ba_node );
4343     IXMLDOMNodeList_Release( fo_list );
4344
4345     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4346     ok( r == S_OK, "ret %08x\n", r);
4347
4348     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4349     ok( r == S_OK, "ret %08x\n", r);
4350
4351     /* MS quirk: passing wrong interface pointer works, too */
4352     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4353     ok( r == S_OK, "ret %08x\n", r);
4354     IXMLDOMElement_Release( lc_element );
4355
4356     temp_node = (void*)0xdeadbeef;
4357     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4358     ok( r == S_FALSE, "ret %08x\n", r);
4359     ok( temp_node == NULL, "%p\n", temp_node );
4360
4361     IXMLDOMNode_Release( lc_node );
4362     IXMLDOMNodeList_Release( root_list );
4363     IXMLDOMElement_Release( element );
4364     IXMLDOMDocument_Release( doc );
4365
4366     free_bstrs();
4367 }
4368
4369 static void test_replaceChild(void)
4370 {
4371     HRESULT r;
4372     VARIANT_BOOL b;
4373     IXMLDOMDocument *doc;
4374     IXMLDOMElement *element, *ba_element;
4375     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4376     IXMLDOMNodeList *root_list, *fo_list;
4377     IUnknown * unk1, *unk2;
4378     LONG len;
4379
4380     doc = create_document(&IID_IXMLDOMDocument);
4381     if (!doc) return;
4382
4383     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4384     ok( r == S_OK, "loadXML failed\n");
4385     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4386
4387     r = IXMLDOMDocument_get_documentElement( doc, &element );
4388     ok( r == S_OK, "ret %08x\n", r);
4389
4390     r = IXMLDOMElement_get_childNodes( element, &root_list );
4391     ok( r == S_OK, "ret %08x\n", r);
4392
4393     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4394     ok( r == S_OK, "ret %08x\n", r);
4395
4396     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4397     ok( r == S_OK, "ret %08x\n", r);
4398
4399     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4400     ok( r == S_OK, "ret %08x\n", r);
4401
4402     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4403     ok( r == S_OK, "ret %08x\n", r);
4404
4405     IXMLDOMNodeList_Release( fo_list );
4406
4407     /* invalid parameter: NULL ptr for element to remove */
4408     removed_node = (void*)0xdeadbeef;
4409     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4410     ok( r == E_INVALIDARG, "ret %08x\n", r );
4411     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4412
4413     /* invalid parameter: NULL for replacement element. (Sic!) */
4414     removed_node = (void*)0xdeadbeef;
4415     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4416     ok( r == E_INVALIDARG, "ret %08x\n", r );
4417     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4418
4419     /* invalid parameter: OldNode is not a child */
4420     removed_node = (void*)0xdeadbeef;
4421     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4422     ok( r == E_INVALIDARG, "ret %08x\n", r );
4423     ok( removed_node == NULL, "%p\n", removed_node );
4424     IXMLDOMNode_Release( lc_node );
4425
4426     /* invalid parameter: would create loop */
4427     removed_node = (void*)0xdeadbeef;
4428     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4429     ok( r == E_FAIL, "ret %08x\n", r );
4430     ok( removed_node == NULL, "%p\n", removed_node );
4431
4432     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4433     ok( r == S_OK, "ret %08x\n", r );
4434
4435     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4436     ok( r == S_OK, "ret %08x\n", r );
4437
4438     /* ba_node and temp_node refer to the same node, yet they
4439        are different interface pointers */
4440     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4441     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4442     ok( r == S_OK, "ret %08x\n", r );
4443     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4444     ok( r == S_OK, "ret %08x\n", r );
4445     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4446
4447     IUnknown_Release( unk1 );
4448     IUnknown_Release( unk2 );
4449
4450     /* ba_node should have been removed from below fo_node */
4451     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4452     ok( r == S_OK, "ret %08x\n", r );
4453
4454     /* MS quirk: replaceChild also accepts elements instead of nodes */
4455     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4456     ok( r == S_OK, "ret %08x\n", r );
4457     EXPECT_REF(ba_element, 2);
4458
4459     removed_node = NULL;
4460     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4461     ok( r == S_OK, "ret %08x\n", r );
4462     ok( removed_node != NULL, "got %p\n", removed_node);
4463     EXPECT_REF(ba_element, 3);
4464     IXMLDOMElement_Release( ba_element );
4465
4466     r = IXMLDOMNodeList_get_length( fo_list, &len);
4467     ok( r == S_OK, "ret %08x\n", r );
4468     ok( len == 0, "len %d\n", len);
4469
4470     IXMLDOMNodeList_Release( fo_list );
4471
4472     IXMLDOMNode_Release(ba_node);
4473     IXMLDOMNode_Release(fo_node);
4474     IXMLDOMNode_Release(temp_node);
4475     IXMLDOMNodeList_Release( root_list );
4476     IXMLDOMElement_Release( element );
4477     IXMLDOMDocument_Release( doc );
4478
4479     free_bstrs();
4480 }
4481
4482 static void test_removeNamedItem(void)
4483 {
4484     IXMLDOMDocument *doc;
4485     IXMLDOMElement *element;
4486     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4487     IXMLDOMNodeList *root_list;
4488     IXMLDOMNamedNodeMap * pr_attrs;
4489     VARIANT_BOOL b;
4490     BSTR str;
4491     LONG len;
4492     HRESULT r;
4493
4494     doc = create_document(&IID_IXMLDOMDocument);
4495     if (!doc) return;
4496
4497     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4498     ok( r == S_OK, "loadXML failed\n");
4499     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4500
4501     r = IXMLDOMDocument_get_documentElement( doc, &element );
4502     ok( r == S_OK, "ret %08x\n", r);
4503
4504     r = IXMLDOMElement_get_childNodes( element, &root_list );
4505     ok( r == S_OK, "ret %08x\n", r);
4506
4507     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4508     ok( r == S_OK, "ret %08x\n", r);
4509
4510     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4511     ok( r == S_OK, "ret %08x\n", r);
4512
4513     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4514     ok( r == S_OK, "ret %08x\n", r);
4515     ok( len == 3, "length %d\n", len);
4516
4517     removed_node = (void*)0xdeadbeef;
4518     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4519     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4520     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4521
4522     removed_node = (void*)0xdeadbeef;
4523     str = SysAllocString(szvr);
4524     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4525     ok ( r == S_OK, "ret %08x\n", r);
4526
4527     removed_node2 = (void*)0xdeadbeef;
4528     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4529     ok ( r == S_FALSE, "ret %08x\n", r);
4530     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4531
4532     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4533     ok( r == S_OK, "ret %08x\n", r);
4534     ok( len == 2, "length %d\n", len);
4535
4536     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4537     ok ( r == S_OK, "ret %08x\n", r);
4538     IXMLDOMNode_Release(removed_node);
4539
4540     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4541     ok( r == S_OK, "ret %08x\n", r);
4542     ok( len == 3, "length %d\n", len);
4543
4544     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4545     ok ( r == S_OK, "ret %08x\n", r);
4546
4547     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4548     ok( r == S_OK, "ret %08x\n", r);
4549     ok( len == 2, "length %d\n", len);
4550
4551     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4552     ok ( r == S_FALSE, "ret %08x\n", r);
4553
4554     SysFreeString(str);
4555
4556     IXMLDOMNamedNodeMap_Release( pr_attrs );
4557     IXMLDOMNode_Release( pr_node );
4558     IXMLDOMNodeList_Release( root_list );
4559     IXMLDOMElement_Release( element );
4560     IXMLDOMDocument_Release( doc );
4561
4562     free_bstrs();
4563 }
4564
4565 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4566 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4567                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4568                                     DWORD expected2)
4569 {
4570     DWORD enabled, supported;
4571     HRESULT hr;
4572
4573     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4574     if (result == result2)
4575         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4576     else
4577         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4578            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4579
4580     supported = enabled = 0xCAFECAFE;
4581     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4582     ok(hr == S_OK, "ret %08x\n", hr );
4583     if (expected == expected2)
4584         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4585     else
4586         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4587            "Expected %08x, got %08x\n", expected2, enabled);
4588
4589     /* reset the safety options */
4590
4591     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4592             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4593             0);
4594     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4595
4596     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4597     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4598     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4599 }
4600
4601 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4602 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4603 {
4604     DWORD enabled = 0, supported = 0;
4605     HRESULT hr;
4606
4607     /* get */
4608     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4609     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4610     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4611     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4612
4613     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4614     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4615     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4616        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4617         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4618              "got %08x\n", supported);
4619     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4620
4621     /* set -- individual flags */
4622
4623     test_IObjectSafety_set(safety, S_OK, S_OK,
4624         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4625         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4626
4627     test_IObjectSafety_set(safety, S_OK, S_OK,
4628         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4629         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4630
4631     test_IObjectSafety_set(safety, S_OK, S_OK,
4632         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4633         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4634
4635     /* set INTERFACE_USES_DISPEX  */
4636
4637     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4638         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4639         0, 0);
4640
4641     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4642         INTERFACE_USES_DISPEX, 0,
4643         0, 0);
4644
4645     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4646         0, INTERFACE_USES_DISPEX,
4647         0, 0);
4648
4649     /* set option masking */
4650
4651     test_IObjectSafety_set(safety, S_OK, S_OK,
4652         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4653         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4654         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4655         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4656
4657     test_IObjectSafety_set(safety, S_OK, S_OK,
4658         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4659         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4660         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4661         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4662
4663     test_IObjectSafety_set(safety, S_OK, S_OK,
4664         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4665         INTERFACE_USES_SECURITY_MANAGER,
4666         0,
4667         0);
4668
4669     /* set -- inheriting previous settings */
4670
4671     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4672                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4673                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4674     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4675     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4676     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4677     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4678     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4679        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4680         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4681              "got %08x\n", supported);
4682
4683     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4684                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4685                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4686     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4687     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4688     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4689     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4690                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4691                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4692     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4693        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4694         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4695              "got %08x\n", supported);
4696 }
4697
4698 static void test_XMLHTTP(void)
4699 {
4700     static const char bodyA[] = "mode=Test";
4701     static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
4702     static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
4703     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4704     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4705
4706     IXMLHttpRequest *xhr;
4707     IObjectSafety *safety;
4708     IObjectWithSite *obj_site, *obj_site2;
4709     BSTR bstrResponse, str, str1;
4710     VARIANT varbody, varbody_ref;
4711     VARIANT dummy;
4712     VARIANT async;
4713     LONG state, status, bound;
4714     IDispatch *event;
4715     void *ptr;
4716     HRESULT hr;
4717     HGLOBAL g;
4718
4719     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4720         &IID_IXMLHttpRequest, (void**)&xhr);
4721     if (FAILED(hr))
4722     {
4723         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4724         return;
4725     }
4726
4727     VariantInit(&dummy);
4728     V_VT(&dummy) = VT_ERROR;
4729     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4730     VariantInit(&async);
4731     V_VT(&async) = VT_BOOL;
4732     V_BOOL(&async) = VARIANT_FALSE;
4733
4734     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4735     EXPECT_HR(hr, S_OK);
4736
4737     hr = IXMLHttpRequest_abort(xhr);
4738     EXPECT_HR(hr, S_OK);
4739
4740     V_VT(&varbody) = VT_I2;
4741     V_I2(&varbody) = 1;
4742     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4743     EXPECT_HR(hr, E_PENDING);
4744     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4745     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4746
4747     V_VT(&varbody) = VT_I2;
4748     V_I2(&varbody) = 1;
4749     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4750     EXPECT_HR(hr, E_PENDING);
4751     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4752     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4753
4754     /* send before open */
4755     hr = IXMLHttpRequest_send(xhr, dummy);
4756     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4757
4758     /* initial status code */
4759     hr = IXMLHttpRequest_get_status(xhr, NULL);
4760     EXPECT_HR(hr, E_INVALIDARG);
4761
4762     status = 0xdeadbeef;
4763     hr = IXMLHttpRequest_get_status(xhr, &status);
4764     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4765     ok(status == 0xdeadbeef, "got %d\n", status);
4766
4767     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4768     ok(hr == E_FAIL, "got 0x%08x\n", hr);
4769
4770     /* invalid parameters */
4771     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4772     EXPECT_HR(hr, E_INVALIDARG);
4773
4774     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4775     EXPECT_HR(hr, E_INVALIDARG);
4776
4777     hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
4778     EXPECT_HR(hr, E_INVALIDARG);
4779
4780     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4781     EXPECT_HR(hr, E_INVALIDARG);
4782
4783     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4784     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4785
4786     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4787     EXPECT_HR(hr, E_INVALIDARG);
4788
4789     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4790     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4791
4792     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4793     EXPECT_HR(hr, E_INVALIDARG);
4794
4795     state = -1;
4796     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4797     EXPECT_HR(hr, S_OK);
4798     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4799
4800     event = create_dispevent();
4801
4802     EXPECT_REF(event, 1);
4803     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4804     EXPECT_HR(hr, S_OK);
4805     EXPECT_REF(event, 2);
4806
4807     g_unexpectedcall = g_expectedcall = 0;
4808
4809     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4810     EXPECT_HR(hr, S_OK);
4811
4812     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4813     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4814
4815     /* status code after ::open() */
4816     status = 0xdeadbeef;
4817     hr = IXMLHttpRequest_get_status(xhr, &status);
4818     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4819     ok(status == 0xdeadbeef, "got %d\n", status);
4820
4821     state = -1;
4822     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4823     EXPECT_HR(hr, S_OK);
4824     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4825
4826     hr = IXMLHttpRequest_abort(xhr);
4827     EXPECT_HR(hr, S_OK);
4828
4829     state = -1;
4830     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4831     EXPECT_HR(hr, S_OK);
4832     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4833         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4834
4835     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4836     EXPECT_HR(hr, S_OK);
4837
4838     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4839     EXPECT_HR(hr, S_OK);
4840
4841     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4842     EXPECT_HR(hr, E_INVALIDARG);
4843
4844     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4845     EXPECT_HR(hr, E_INVALIDARG);
4846
4847     V_VT(&varbody) = VT_BSTR;
4848     V_BSTR(&varbody) = _bstr_(bodyA);
4849
4850     hr = IXMLHttpRequest_send(xhr, varbody);
4851     if (hr == INET_E_RESOURCE_NOT_FOUND)
4852     {
4853         skip("No connection could be made with crossover.codeweavers.com\n");
4854         IXMLHttpRequest_Release(xhr);
4855         return;
4856     }
4857     EXPECT_HR(hr, S_OK);
4858
4859     /* response headers */
4860     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
4861     EXPECT_HR(hr, E_INVALIDARG);
4862     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
4863     EXPECT_HR(hr, S_OK);
4864     /* status line is stripped already */
4865     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
4866     ok(*str, "got empty headers\n");
4867     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
4868     EXPECT_HR(hr, S_OK);
4869     ok(str1 != str, "got %p\n", str1);
4870     SysFreeString(str1);
4871     SysFreeString(str);
4872
4873     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
4874     EXPECT_HR(hr, E_INVALIDARG);
4875     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
4876     EXPECT_HR(hr, E_INVALIDARG);
4877     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
4878     EXPECT_HR(hr, S_OK);
4879     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
4880     SysFreeString(str);
4881
4882     /* status code after ::send() */
4883     status = 0xdeadbeef;
4884     hr = IXMLHttpRequest_get_status(xhr, &status);
4885     EXPECT_HR(hr, S_OK);
4886     ok(status == 200, "got %d\n", status);
4887
4888     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
4889     EXPECT_HR(hr, E_INVALIDARG);
4890
4891     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4892     EXPECT_HR(hr, S_OK);
4893     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
4894     SysFreeString(str);
4895
4896     /* another ::send() after completed request */
4897     V_VT(&varbody) = VT_BSTR;
4898     V_BSTR(&varbody) = _bstr_(bodyA);
4899
4900     hr = IXMLHttpRequest_send(xhr, varbody);
4901     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4902
4903     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4904     EXPECT_HR(hr, S_OK);
4905     /* the server currently returns "FAILED" because the Content-Type header is
4906      * not what the server expects */
4907     if(hr == S_OK)
4908     {
4909         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4910             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4911         SysFreeString(bstrResponse);
4912     }
4913
4914     /* POST: VT_VARIANT|VT_BYREF body */
4915     V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
4916     V_VARIANTREF(&varbody_ref) = &varbody;
4917     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4918     EXPECT_HR(hr, S_OK);
4919     hr = IXMLHttpRequest_send(xhr, varbody_ref);
4920     EXPECT_HR(hr, S_OK);
4921
4922     /* GET request */
4923     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
4924     EXPECT_HR(hr, S_OK);
4925
4926     V_VT(&varbody) = VT_EMPTY;
4927
4928     hr = IXMLHttpRequest_send(xhr, varbody);
4929     if (hr == INET_E_RESOURCE_NOT_FOUND)
4930     {
4931         skip("No connection could be made with crossover.codeweavers.com\n");
4932         IXMLHttpRequest_Release(xhr);
4933         return;
4934     }
4935     EXPECT_HR(hr, S_OK);
4936
4937     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4938     EXPECT_HR(hr, E_INVALIDARG);
4939
4940     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4941     EXPECT_HR(hr, S_OK);
4942     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4943         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4944     SysFreeString(bstrResponse);
4945
4946     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4947     EXPECT_HR(hr, E_INVALIDARG);
4948
4949     V_VT(&varbody) = VT_EMPTY;
4950     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4951     EXPECT_HR(hr, S_OK);
4952     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4953     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4954
4955     bound = -1;
4956     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4957     EXPECT_HR(hr, S_OK);
4958     ok(bound == 0, "got %d, expected zero bound\n", bound);
4959
4960     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4961     EXPECT_HR(hr, S_OK);
4962     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4963     SafeArrayUnaccessData(V_ARRAY(&varbody));
4964
4965     VariantClear(&varbody);
4966
4967     /* get_responseStream */
4968     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
4969     EXPECT_HR(hr, E_INVALIDARG);
4970
4971     V_VT(&varbody) = VT_EMPTY;
4972     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4973     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
4974     EXPECT_HR(hr, S_OK);
4975     EXPECT_REF(V_UNKNOWN(&varbody), 1);
4976
4977     g = NULL;
4978     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
4979     EXPECT_HR(hr, S_OK);
4980     ok(g != NULL, "got %p\n", g);
4981
4982     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4983     EXPECT_HR(hr, S_OK);
4984     if(hr == S_OK)
4985     {
4986         test_IObjectSafety_common(safety);
4987         IObjectSafety_Release(safety);
4988     }
4989
4990     IDispatch_Release(event);
4991
4992     /* interaction with object site */
4993     EXPECT_REF(xhr, 1);
4994     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4995     EXPECT_HR(hr, S_OK);
4996 todo_wine {
4997     EXPECT_REF(xhr, 1);
4998     EXPECT_REF(obj_site, 1);
4999 }
5000
5001     IObjectWithSite_AddRef(obj_site);
5002 todo_wine {
5003     EXPECT_REF(obj_site, 2);
5004     EXPECT_REF(xhr, 1);
5005 }
5006     IObjectWithSite_Release(obj_site);
5007
5008     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
5009     EXPECT_HR(hr, S_OK);
5010 todo_wine {
5011     EXPECT_REF(xhr, 1);
5012     EXPECT_REF(obj_site, 1);
5013     EXPECT_REF(obj_site2, 1);
5014     ok(obj_site != obj_site2, "expected new instance\n");
5015 }
5016     SET_EXPECT(site_qi_IServiceProvider);
5017     SET_EXPECT(sp_queryservice_SID_SBindHost);
5018     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5019     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
5020     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
5021     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
5022
5023     /* calls to IHTMLDocument2 */
5024     SET_EXPECT(htmldoc2_get_all);
5025     SET_EXPECT(collection_get_length);
5026     SET_EXPECT(htmldoc2_get_url);
5027
5028     SET_EXPECT(site_qi_IXMLDOMDocument);
5029     SET_EXPECT(site_qi_IOleClientSite);
5030
5031     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
5032     EXPECT_HR(hr, S_OK);
5033
5034     CHECK_CALLED(site_qi_IServiceProvider);
5035 todo_wine
5036     CHECK_CALLED(sp_queryservice_SID_SBindHost);
5037     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5038 todo_wine {
5039     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
5040     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
5041     /* this one isn't very reliable
5042     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
5043
5044     CHECK_CALLED(htmldoc2_get_all);
5045     CHECK_CALLED(collection_get_length);
5046     CHECK_CALLED(htmldoc2_get_url);
5047
5048     CHECK_CALLED(site_qi_IXMLDOMDocument);
5049     CHECK_CALLED(site_qi_IOleClientSite);
5050 }
5051     IObjectWithSite_Release(obj_site);
5052
5053     /* try to set site another time */
5054
5055     /* to be removed once IObjectWithSite is properly separated */
5056     SET_EXPECT(site_qi_IServiceProvider);
5057     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5058
5059     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5060     EXPECT_HR(hr, S_OK);
5061
5062     todo_wine EXPECT_REF(xhr, 1);
5063     IXMLHttpRequest_Release(xhr);
5064
5065     /* still works after request is released */
5066
5067     /* to be removed once IObjectWithSite is properly separated */
5068     SET_EXPECT(site_qi_IServiceProvider);
5069     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5070
5071     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5072     EXPECT_HR(hr, S_OK);
5073     IObjectWithSite_Release(obj_site2);
5074
5075     free_bstrs();
5076 }
5077
5078 static void test_IXMLDOMDocument2(void)
5079 {
5080     static const WCHAR emptyW[] = {0};
5081     IXMLDOMDocument2 *doc2, *dtddoc2;
5082     IXMLDOMDocument *doc;
5083     IXMLDOMParseError* err;
5084     IDispatchEx *dispex;
5085     VARIANT_BOOL b;
5086     VARIANT var;
5087     HRESULT r;
5088     LONG res;
5089
5090     doc = create_document(&IID_IXMLDOMDocument);
5091     if (!doc) return;
5092
5093     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
5094     if (!dtddoc2)
5095     {
5096         IXMLDOMDocument_Release(doc);
5097         return;
5098     }
5099
5100     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
5101     ok( r == S_OK, "ret %08x\n", r );
5102     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
5103
5104     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
5105     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
5106     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5107
5108     err = NULL;
5109     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
5110     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5111     ok(err != NULL, "expected a pointer\n");
5112     if (err)
5113     {
5114         res = 0;
5115         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5116         /* XML_E_NOTWF */
5117         ok(res == E_XML_NOTWF, "got %08x\n", res);
5118         IXMLDOMParseError_Release(err);
5119     }
5120
5121     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
5122     ok( r == S_OK, "loadXML failed\n");
5123     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5124
5125     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
5126     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5127
5128     err = NULL;
5129     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5130     ok(err != NULL, "expected a pointer\n");
5131     if (err)
5132     {
5133         res = 0;
5134         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5135         /* XML_E_NODTD */
5136         ok(res == E_XML_NODTD, "got %08x\n", res);
5137         IXMLDOMParseError_Release(err);
5138     }
5139
5140     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5141     ok( r == S_OK, "ret %08x\n", r );
5142     if(r == S_OK)
5143     {
5144         IDispatchEx_Release(dispex);
5145     }
5146
5147     /* we will check if the variant got cleared */
5148     IXMLDOMDocument2_AddRef(doc2);
5149     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5150
5151     V_VT(&var) = VT_UNKNOWN;
5152     V_UNKNOWN(&var) = (IUnknown *)doc2;
5153
5154     /* invalid calls */
5155     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5156     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5157     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5158
5159     /* valid call */
5160     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5161     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5162     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5163     V_VT(&var) = VT_R4;
5164
5165     /* the variant didn't get cleared*/
5166     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5167
5168     /* setProperty tests */
5169     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5170     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5171     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5172     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5173     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5174     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5175
5176     V_VT(&var) = VT_BSTR;
5177     V_BSTR(&var) = SysAllocString(emptyW);
5178     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5179     ok(r == S_OK, "got 0x%08x\n", r);
5180     VariantClear(&var);
5181
5182     V_VT(&var) = VT_I2;
5183     V_I2(&var) = 0;
5184     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5185     ok(r == E_FAIL, "got 0x%08x\n", r);
5186
5187     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5188     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5189     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5190     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5191
5192     IXMLDOMDocument2_Release( doc2 );
5193     IXMLDOMDocument_Release( doc );
5194
5195     /* DTD validation */
5196     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5197     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5198     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5199     err = NULL;
5200     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5201     ok(err != NULL, "expected pointer\n");
5202     if (err)
5203     {
5204         res = 0;
5205         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5206         ok(res == 0, "got %08x\n", res);
5207         IXMLDOMParseError_Release(err);
5208     }
5209
5210     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5211     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5212     err = NULL;
5213     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5214     ok(err != NULL, "expected pointer\n");
5215     if (err)
5216     {
5217         res = 0;
5218         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5219         /* XML_ELEMENT_UNDECLARED */
5220         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5221         IXMLDOMParseError_Release(err);
5222     }
5223
5224     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5225     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5226     err = NULL;
5227     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5228     ok(err != NULL, "expected pointer\n");
5229     if (err)
5230     {
5231         res = 0;
5232         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5233         /* XML_ELEMENT_ID_NOT_FOUND */
5234         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5235         IXMLDOMParseError_Release(err);
5236     }
5237
5238     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5239     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5240     err = NULL;
5241     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5242     ok(err != NULL, "expected pointer\n");
5243     if (err)
5244     {
5245         res = 0;
5246         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5247         /* XML_EMPTY_NOT_ALLOWED */
5248         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5249         IXMLDOMParseError_Release(err);
5250     }
5251
5252     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5253     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5254     err = NULL;
5255     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5256     ok(err != NULL, "expected pointer\n");
5257     if (err)
5258     {
5259         res = 0;
5260         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5261         /* XML_ROOT_NAME_MISMATCH */
5262         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5263         IXMLDOMParseError_Release(err);
5264     }
5265
5266     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5267     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5268     err = NULL;
5269     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5270     ok(err != NULL, "expected pointer\n");
5271     if (err)
5272     {
5273         res = 0;
5274         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5275         /* XML_INVALID_CONTENT */
5276         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5277         IXMLDOMParseError_Release(err);
5278     }
5279
5280     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5281     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5282     err = NULL;
5283     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5284     ok(err != NULL, "expected pointer\n");
5285     if (err)
5286     {
5287         res = 0;
5288         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5289         /* XML_ATTRIBUTE_NOT_DEFINED */
5290         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5291         IXMLDOMParseError_Release(err);
5292     }
5293
5294     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5295     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5296     err = NULL;
5297     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5298     ok(err != NULL, "expected pointer\n");
5299     if (err)
5300     {
5301         res = 0;
5302         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5303         /* XML_ATTRIBUTE_FIXED */
5304         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5305         IXMLDOMParseError_Release(err);
5306     }
5307
5308     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5309     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5310     err = NULL;
5311     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5312     ok(err != NULL, "expected pointer\n");
5313     if (err)
5314     {
5315         res = 0;
5316         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5317         /* XML_ATTRIBUTE_VALUE */
5318         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5319         IXMLDOMParseError_Release(err);
5320     }
5321
5322     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5323     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5324     err = NULL;
5325     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5326     ok(err != NULL, "expected pointer\n");
5327     if (err)
5328     {
5329         res = 0;
5330         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5331         /* XML_ILLEGAL_TEXT */
5332         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5333         IXMLDOMParseError_Release(err);
5334     }
5335
5336     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5337     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5338     err = NULL;
5339     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5340     ok(err != NULL, "expected pointer\n");
5341     if (err)
5342     {
5343         res = 0;
5344         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5345         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5346         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5347         IXMLDOMParseError_Release(err);
5348     }
5349
5350     IXMLDOMDocument2_Release( dtddoc2 );
5351     free_bstrs();
5352 }
5353
5354 #define helper_ole_check(expr) { \
5355     HRESULT r = expr; \
5356     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5357 }
5358
5359 #define helper_expect_list_and_release(list, expstr) { \
5360     char *str = list_to_string(list); \
5361     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5362     if (list) IXMLDOMNodeList_Release(list); \
5363 }
5364
5365 #define helper_expect_bstr_and_release(bstr, str) { \
5366     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5367        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5368     SysFreeString(bstr); \
5369 }
5370
5371 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5372 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5373 {
5374     IXMLDOMNode *node1, *node2;
5375     IXMLDOMNodeList *list;
5376     BSTR bstr;
5377
5378     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5379     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5380     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5381     helper_ole_check(IXMLDOMNodeList_reset(list));
5382     helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
5383
5384     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5385     helper_expect_list_and_release(list, "T1.E1.E5.E1.E2.D1 E2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 T4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1");
5386     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5387     if (str)
5388     {
5389         helper_expect_bstr_and_release(bstr, str);
5390     }
5391     else
5392     {
5393         helper_expect_bstr_and_release(bstr, "This is a description.");
5394     }
5395     IXMLDOMNode_Release(node1);
5396
5397     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5398     helper_expect_list_and_release(list, "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
5399     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5400     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5401     IXMLDOMNode_Release(node2);
5402 }
5403
5404 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5405 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5406 {
5407     IXMLDOMNode *node1, *node2;
5408     IXMLDOMNodeList *list;
5409     BSTR bstr;
5410
5411     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5412     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5413     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5414     helper_ole_check(IXMLDOMNodeList_reset(list));
5415     helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
5416
5417     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5418     helper_expect_list_and_release(list, "T1.E2.E10.E2.E2.D1 E2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 T7.E2.E10.E2.E2.D1");
5419     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5420     if (str)
5421     {
5422         helper_expect_bstr_and_release(bstr, str);
5423     }
5424     else
5425     {
5426         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5427     }
5428     IXMLDOMNode_Release(node1);
5429
5430     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5431     helper_expect_list_and_release(list, "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
5432     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5433     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5434     IXMLDOMNode_Release(node2);
5435 }
5436
5437 static void test_whitespace(void)
5438 {
5439     VARIANT_BOOL b;
5440     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5441
5442     doc1 = create_document(&IID_IXMLDOMDocument2);
5443     doc2 = create_document(&IID_IXMLDOMDocument2);
5444     if (!doc1 || !doc2) return;
5445
5446     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5447     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5448     ok(b == VARIANT_FALSE, "expected false\n");
5449     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5450     ok(b == VARIANT_TRUE, "expected true\n");
5451
5452     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5453     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5454     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5455     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5456
5457     /* switch to XPath */
5458     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5459     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5460
5461     check_ws_ignored(doc1, NULL);
5462     check_ws_preserved(doc2, NULL);
5463
5464     /* new instances copy the property */
5465     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5466     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5467
5468     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5469     ok(b == VARIANT_FALSE, "expected false\n");
5470     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5471     ok(b == VARIANT_TRUE, "expected true\n");
5472
5473     check_ws_ignored(doc3, NULL);
5474     check_ws_preserved(doc4, NULL);
5475
5476     /* setting after loading xml affects trimming of leading/trailing ws only */
5477     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5478     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5479
5480     /* the trailing "\n            " isn't there, because it was ws-only node */
5481     check_ws_ignored(doc1, "\n                This is a description. ");
5482     check_ws_preserved(doc2, "This is a description.");
5483
5484     /* it takes effect on reload */
5485     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5486     ok(b == VARIANT_TRUE, "expected true\n");
5487     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5488     ok(b == VARIANT_FALSE, "expected false\n");
5489
5490     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5491     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5492     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5493     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5494
5495     check_ws_preserved(doc1, NULL);
5496     check_ws_ignored(doc2, NULL);
5497
5498     /* other instances follow suit */
5499     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5500     ok(b == VARIANT_TRUE, "expected true\n");
5501     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5502     ok(b == VARIANT_FALSE, "expected false\n");
5503
5504     check_ws_preserved(doc3, NULL);
5505     check_ws_ignored(doc4, NULL);
5506
5507     IXMLDOMDocument_Release(doc1);
5508     IXMLDOMDocument_Release(doc2);
5509     IXMLDOMDocument_Release(doc3);
5510     IXMLDOMDocument_Release(doc4);
5511     free_bstrs();
5512 }
5513
5514 typedef struct {
5515     const GUID *clsid;
5516     const char *name;
5517     const char *ns;
5518     HRESULT hr;
5519 } selection_ns_t;
5520
5521 /* supposed to be tested with szExampleXML */
5522 static const selection_ns_t selection_ns_data[] = {
5523     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5524     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5525     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5526
5527     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5528     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5529     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5530
5531     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5532     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5533     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5534
5535     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5536     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5537     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5538
5539     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5540     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5541     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5542
5543     { NULL }
5544 };
5545
5546 static void test_XPath(void)
5547 {
5548     const selection_ns_t *ptr = selection_ns_data;
5549     VARIANT var;
5550     VARIANT_BOOL b;
5551     IXMLDOMDocument2 *doc;
5552     IXMLDOMDocument *doc2;
5553     IXMLDOMNode *rootNode;
5554     IXMLDOMNode *elem1Node;
5555     IXMLDOMNode *node;
5556     IXMLDOMNodeList *list;
5557     IXMLDOMElement *elem;
5558     IXMLDOMAttribute *attr;
5559     DOMNodeType type;
5560     HRESULT hr;
5561     LONG len;
5562     BSTR str;
5563
5564     doc = create_document(&IID_IXMLDOMDocument2);
5565     if (!doc) return;
5566
5567     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5568     EXPECT_HR(hr, S_OK);
5569     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5570
5571     /* switch to XPath */
5572     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5573
5574     /* some simple queries*/
5575     EXPECT_REF(doc, 1);
5576     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5577     EXPECT_HR(hr, S_OK);
5578     EXPECT_REF(doc, 1);
5579     EXPECT_LIST_LEN(list, 1);
5580
5581     EXPECT_REF(list, 1);
5582     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5583     EXPECT_HR(hr, S_OK);
5584     EXPECT_REF(list, 1);
5585     EXPECT_REF(rootNode, 1);
5586
5587     hr = IXMLDOMNodeList_reset(list);
5588     EXPECT_HR(hr, S_OK);
5589     expect_list_and_release(list, "E2.D1");
5590
5591 if (0)
5592 {
5593     /* namespace:: axis test is disabled until namespace definitions
5594        are supported as attribute nodes, currently it's another node type */
5595     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5596     EXPECT_HR(hr, S_OK);
5597     len = -1;
5598     hr = IXMLDOMNodeList_get_length(list, &len);
5599     EXPECT_HR(hr, S_OK);
5600     ok(len == 2, "got %d\n", len);
5601
5602     hr = IXMLDOMNodeList_nextNode(list, &node);
5603     EXPECT_HR(hr, S_OK);
5604     type = NODE_INVALID;
5605     hr = IXMLDOMNode_get_nodeType(node, &type);
5606     EXPECT_HR(hr, S_OK);
5607     ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5608     IXMLDOMNode_Release(node);
5609
5610     IXMLDOMNodeList_Release(list);
5611 }
5612
5613     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5614     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5615
5616     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5617     expect_list_and_release(list, "E3.E2.E2.D1");
5618
5619     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5620     /* using get_item for query results advances the position */
5621     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5622     expect_node(node, "E2.E2.D1");
5623     IXMLDOMNode_Release(node);
5624     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5625     expect_node(node, "E4.E2.D1");
5626     IXMLDOMNode_Release(node);
5627     ole_check(IXMLDOMNodeList_reset(list));
5628     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5629
5630     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5631     expect_list_and_release(list, "E2.D1");
5632
5633     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5634     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5635     ole_check(IXMLDOMNodeList_reset(list));
5636     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5637
5638     /* select an attribute */
5639     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5640     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5641
5642     /* would evaluate to a number */
5643     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5644     /* would evaluate to a boolean */
5645     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5646     /* would evaluate to a string */
5647     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5648
5649     /* no results */
5650     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5651     expect_list_and_release(list, "");
5652     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5653     expect_list_and_release(list, "");
5654     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5655     expect_list_and_release(list, "");
5656     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5657     expect_list_and_release(list, "");
5658
5659     /* foo undeclared in document node */
5660     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5661     /* undeclared in <root> node */
5662     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5663     /* undeclared in <elem> node */
5664     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5665     /* but this trick can be used */
5666     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5667     expect_list_and_release(list, "E3.E4.E2.D1");
5668
5669     /* it has to be declared in SelectionNamespaces */
5670     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5671         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5672
5673     /* now the namespace can be used */
5674     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5675     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5676     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5677     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5678     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5679     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5680     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5681     expect_list_and_release(list, "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
5682
5683     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5684     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5685         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5686
5687     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5688
5689     VariantInit(&var);
5690     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5691     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5692     if (V_VT(&var) == VT_BSTR)
5693         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5694
5695     /* extra attributes - same thing*/
5696     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5697         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5698     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5699
5700     IXMLDOMNode_Release(rootNode);
5701     IXMLDOMNode_Release(elem1Node);
5702
5703     /* alter document with already built list */
5704     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5705     EXPECT_HR(hr, S_OK);
5706     EXPECT_LIST_LEN(list, 1);
5707
5708     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5709     EXPECT_HR(hr, S_OK);
5710     EXPECT_REF(rootNode, 1);
5711     EXPECT_REF(doc, 1);
5712
5713     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5714     EXPECT_HR(hr, S_OK);
5715     IXMLDOMNode_Release(rootNode);
5716
5717     EXPECT_LIST_LEN(list, 1);
5718
5719     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5720     EXPECT_HR(hr, S_OK);
5721     EXPECT_REF(rootNode, 1);
5722
5723     IXMLDOMNodeList_Release(list);
5724
5725     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5726     EXPECT_HR(hr, S_OK);
5727     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5728     SysFreeString(str);
5729     IXMLDOMNode_Release(rootNode);
5730
5731     /* alter node from list and get it another time */
5732     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5733     EXPECT_HR(hr, S_OK);
5734     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5735
5736     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5737     EXPECT_HR(hr, S_OK);
5738     EXPECT_LIST_LEN(list, 1);
5739
5740     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5741     EXPECT_HR(hr, S_OK);
5742
5743     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5744     EXPECT_HR(hr, S_OK);
5745
5746     V_VT(&var) = VT_I2;
5747     V_I2(&var) = 1;
5748     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5749     EXPECT_HR(hr, S_OK);
5750     IXMLDOMElement_Release(elem);
5751     IXMLDOMNode_Release(rootNode);
5752
5753     /* now check attribute to be present */
5754     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5755     EXPECT_HR(hr, S_OK);
5756
5757     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5758     EXPECT_HR(hr, S_OK);
5759
5760     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5761     EXPECT_HR(hr, S_OK);
5762     IXMLDOMAttribute_Release(attr);
5763
5764     IXMLDOMElement_Release(elem);
5765     IXMLDOMNode_Release(rootNode);
5766
5767     /* and now check for attribute in original document */
5768     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5769     EXPECT_HR(hr, S_OK);
5770
5771     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5772     EXPECT_HR(hr, S_OK);
5773     IXMLDOMAttribute_Release(attr);
5774
5775     IXMLDOMElement_Release(elem);
5776
5777     /* attach node from list to another document */
5778     doc2 = create_document(&IID_IXMLDOMDocument);
5779
5780     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5781     EXPECT_HR(hr, S_OK);
5782     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5783
5784     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5785     EXPECT_HR(hr, S_OK);
5786     EXPECT_LIST_LEN(list, 1);
5787
5788     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5789     EXPECT_HR(hr, S_OK);
5790     EXPECT_REF(rootNode, 1);
5791
5792     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5793     EXPECT_HR(hr, S_OK);
5794     EXPECT_REF(rootNode, 1);
5795     EXPECT_REF(doc2, 1);
5796     EXPECT_REF(list, 1);
5797
5798     EXPECT_LIST_LEN(list, 1);
5799
5800     IXMLDOMNode_Release(rootNode);
5801     IXMLDOMNodeList_Release(list);
5802     IXMLDOMDocument_Release(doc2);
5803     IXMLDOMDocument2_Release(doc);
5804
5805     while (ptr->clsid)
5806     {
5807         hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5808         if (hr != S_OK)
5809         {
5810             win_skip("can't create instance of %s\n", ptr->name);
5811             ptr++;
5812             continue;
5813         }
5814
5815         hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5816         EXPECT_HR(hr, S_OK);
5817         ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5818
5819         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5820         EXPECT_HR(hr, S_OK);
5821
5822         V_VT(&var) = VT_BSTR;
5823         V_BSTR(&var) = _bstr_(ptr->ns);
5824
5825         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5826         ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5827
5828         V_VT(&var) = VT_EMPTY;
5829         hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5830         EXPECT_HR(hr, S_OK);
5831         ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5832         ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5833         VariantClear(&var);
5834
5835         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5836         EXPECT_HR(hr, S_OK);
5837         if (hr == S_OK)
5838             expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5839
5840         IXMLDOMDocument2_Release(doc);
5841         ptr++;
5842     }
5843
5844     free_bstrs();
5845 }
5846
5847 static void test_cloneNode(void )
5848 {
5849     IXMLDOMDocument *doc, *doc2;
5850     VARIANT_BOOL b;
5851     IXMLDOMNodeList *pList;
5852     IXMLDOMNamedNodeMap *mapAttr;
5853     LONG length, length1;
5854     LONG attr_cnt, attr_cnt1;
5855     IXMLDOMNode *node;
5856     IXMLDOMNode *node_clone;
5857     IXMLDOMNode *node_first;
5858     HRESULT hr;
5859
5860     doc = create_document(&IID_IXMLDOMDocument);
5861     if (!doc) return;
5862
5863     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5864     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5865
5866     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5867     ok( hr == S_OK, "ret %08x\n", hr );
5868     ok( node != NULL, "node %p\n", node );
5869
5870     /* Check invalid parameter */
5871     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5872     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5873
5874     /* All Children */
5875     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5876     ok( hr == S_OK, "ret %08x\n", hr );
5877     ok( node_clone != NULL, "node %p\n", node );
5878
5879     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5880     ok( hr == S_OK, "ret %08x\n", hr );
5881     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5882     ok( hr == S_OK, "ret %08x\n", hr );
5883     IXMLDOMDocument_Release(doc2);
5884     IXMLDOMNode_Release(node_first);
5885
5886     hr = IXMLDOMNode_get_childNodes(node, &pList);
5887     ok( hr == S_OK, "ret %08x\n", hr );
5888     length = 0;
5889     hr = IXMLDOMNodeList_get_length(pList, &length);
5890     ok( hr == S_OK, "ret %08x\n", hr );
5891     ok(length == 1, "got %d\n", length);
5892     IXMLDOMNodeList_Release(pList);
5893
5894     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5895     ok( hr == S_OK, "ret %08x\n", hr );
5896     attr_cnt = 0;
5897     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5898     ok( hr == S_OK, "ret %08x\n", hr );
5899     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5900     IXMLDOMNamedNodeMap_Release(mapAttr);
5901
5902     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5903     ok( hr == S_OK, "ret %08x\n", hr );
5904     length1 = 0;
5905     hr = IXMLDOMNodeList_get_length(pList, &length1);
5906     ok(length1 == 1, "got %d\n", length1);
5907     ok( hr == S_OK, "ret %08x\n", hr );
5908     IXMLDOMNodeList_Release(pList);
5909
5910     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5911     ok( hr == S_OK, "ret %08x\n", hr );
5912     attr_cnt1 = 0;
5913     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5914     ok( hr == S_OK, "ret %08x\n", hr );
5915     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5916     IXMLDOMNamedNodeMap_Release(mapAttr);
5917
5918     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5919     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5920     IXMLDOMNode_Release(node_clone);
5921
5922     /* No Children */
5923     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5924     ok( hr == S_OK, "ret %08x\n", hr );
5925     ok( node_clone != NULL, "node %p\n", node );
5926
5927     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5928     ok(hr == S_FALSE, "ret %08x\n", hr );
5929
5930     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5931     ok(hr == S_OK, "ret %08x\n", hr );
5932     hr = IXMLDOMNodeList_get_length(pList, &length1);
5933     ok(hr == S_OK, "ret %08x\n", hr );
5934     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5935     IXMLDOMNodeList_Release(pList);
5936
5937     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5938     ok(hr == S_OK, "ret %08x\n", hr );
5939     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5940     ok(hr == S_OK, "ret %08x\n", hr );
5941     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5942     IXMLDOMNamedNodeMap_Release(mapAttr);
5943
5944     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5945     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5946     IXMLDOMNode_Release(node_clone);
5947
5948     IXMLDOMNode_Release(node);
5949     IXMLDOMDocument_Release(doc);
5950     free_bstrs();
5951 }
5952
5953 static void test_xmlTypes(void)
5954 {
5955     IXMLDOMDocument *doc;
5956     IXMLDOMElement *pRoot;
5957     HRESULT hr;
5958     IXMLDOMComment *pComment;
5959     IXMLDOMElement *pElement;
5960     IXMLDOMAttribute *pAttribute;
5961     IXMLDOMNamedNodeMap *pAttribs;
5962     IXMLDOMCDATASection *pCDataSec;
5963     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5964     IXMLDOMDocumentFragment *pDocFrag = NULL;
5965     IXMLDOMEntityReference *pEntityRef = NULL;
5966     BSTR str;
5967     IXMLDOMNode *pNextChild;
5968     VARIANT v;
5969     LONG len = 0;
5970
5971     doc = create_document(&IID_IXMLDOMDocument);
5972     if (!doc) return;
5973
5974     pNextChild = (void*)0xdeadbeef;
5975     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5976     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5977
5978     pNextChild = (void*)0xdeadbeef;
5979     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5980     ok(hr == S_FALSE, "ret %08x\n", hr );
5981     ok(pNextChild == NULL, "pDocChild not NULL\n");
5982
5983     /* test previous Sibling */
5984     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5985     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5986
5987     pNextChild = (void*)0xdeadbeef;
5988     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5989     ok(hr == S_FALSE, "ret %08x\n", hr );
5990     ok(pNextChild == NULL, "pNextChild not NULL\n");
5991
5992     /* test get_dataType */
5993     V_VT(&v) = VT_EMPTY;
5994     hr = IXMLDOMDocument_get_dataType(doc, &v);
5995     ok(hr == S_FALSE, "ret %08x\n", hr );
5996     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5997     VariantClear(&v);
5998
5999     /* test implementation */
6000     hr = IXMLDOMDocument_get_implementation(doc, NULL);
6001     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6002
6003     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
6004     ok(hr == S_OK, "ret %08x\n", hr );
6005     if(hr == S_OK)
6006     {
6007         VARIANT_BOOL hasFeature = VARIANT_TRUE;
6008         BSTR sEmpty = SysAllocStringLen(NULL, 0);
6009
6010         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
6011         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6012
6013         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
6014         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6015
6016         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6017         ok(hr == S_OK, "ret %08x\n", hr );
6018         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6019
6020         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
6021         ok(hr == S_OK, "ret %08x\n", hr );
6022         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
6023
6024         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
6025         ok(hr == S_OK, "ret %08x\n", hr );
6026         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
6027
6028         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6029         ok(hr == S_OK, "ret %08x\n", hr );
6030         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6031
6032         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
6033         ok(hr == S_OK, "ret %08x\n", hr );
6034         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6035
6036         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
6037         ok(hr == S_OK, "ret %08x\n", hr );
6038         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6039
6040         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
6041         ok(hr == S_OK, "ret %08x\n", hr );
6042         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6043
6044         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
6045         ok(hr == S_OK, "ret %08x\n", hr );
6046         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6047
6048         SysFreeString(sEmpty);
6049         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
6050     }
6051
6052     pRoot = (IXMLDOMElement*)0x1;
6053     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
6054     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6055     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6056
6057     pRoot = (IXMLDOMElement*)0x1;
6058     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
6059     ok(hr == E_FAIL, "ret %08x\n", hr );
6060     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6061
6062     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6063     ok(hr == S_OK, "ret %08x\n", hr );
6064     if(hr == S_OK)
6065     {
6066         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6067         ok(hr == S_OK, "ret %08x\n", hr );
6068         if(hr == S_OK)
6069         {
6070             /* Comment */
6071             str = SysAllocString(szComment);
6072             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
6073             SysFreeString(str);
6074             ok(hr == S_OK, "ret %08x\n", hr );
6075             if(hr == S_OK)
6076             {
6077                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
6078                 ok(hr == S_OK, "ret %08x\n", hr );
6079
6080                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
6081                 ok(hr == S_OK, "ret %08x\n", hr );
6082                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
6083                 SysFreeString(str);
6084
6085                 hr = IXMLDOMComment_get_xml(pComment, &str);
6086                 ok(hr == S_OK, "ret %08x\n", hr );
6087                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
6088                 SysFreeString(str);
6089
6090                 /* put data Tests */
6091                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
6092                 ok(hr == S_OK, "ret %08x\n", hr );
6093
6094                 /* get data Tests */
6095                 hr = IXMLDOMComment_get_data(pComment, &str);
6096                 ok(hr == S_OK, "ret %08x\n", hr );
6097                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
6098                 SysFreeString(str);
6099
6100                 /* Confirm XML text is good */
6101                 hr = IXMLDOMComment_get_xml(pComment, &str);
6102                 ok(hr == S_OK, "ret %08x\n", hr );
6103                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
6104                 SysFreeString(str);
6105
6106                 /* Confirm we get the put_data Text back */
6107                 hr = IXMLDOMComment_get_text(pComment, &str);
6108                 ok(hr == S_OK, "ret %08x\n", hr );
6109                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
6110                 SysFreeString(str);
6111
6112                 /* test length property */
6113                 hr = IXMLDOMComment_get_length(pComment, &len);
6114                 ok(hr == S_OK, "ret %08x\n", hr );
6115                 ok(len == 21, "expected 21 got %d\n", len);
6116
6117                 /* test substringData */
6118                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
6119                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6120
6121                 /* test substringData - Invalid offset */
6122                 str = (BSTR)&szElement;
6123                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
6124                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6125                 ok( str == NULL, "incorrect string\n");
6126
6127                 /* test substringData - Invalid offset */
6128                 str = (BSTR)&szElement;
6129                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
6130                 ok(hr == S_FALSE, "ret %08x\n", hr );
6131                 ok( str == NULL, "incorrect string\n");
6132
6133                 /* test substringData - Invalid size */
6134                 str = (BSTR)&szElement;
6135                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
6136                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6137                 ok( str == NULL, "incorrect string\n");
6138
6139                 /* test substringData - Invalid size */
6140                 str = (BSTR)&szElement;
6141                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
6142                 ok(hr == S_FALSE, "ret %08x\n", hr );
6143                 ok( str == NULL, "incorrect string\n");
6144
6145                 /* test substringData - Start of string */
6146                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
6147                 ok(hr == S_OK, "ret %08x\n", hr );
6148                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6149                 SysFreeString(str);
6150
6151                 /* test substringData - Middle of string */
6152                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
6153                 ok(hr == S_OK, "ret %08x\n", hr );
6154                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6155                 SysFreeString(str);
6156
6157                 /* test substringData - End of string */
6158                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
6159                 ok(hr == S_OK, "ret %08x\n", hr );
6160                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6161                 SysFreeString(str);
6162
6163                 /* test appendData */
6164                 hr = IXMLDOMComment_appendData(pComment, NULL);
6165                 ok(hr == S_OK, "ret %08x\n", hr );
6166
6167                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
6168                 ok(hr == S_OK, "ret %08x\n", hr );
6169
6170                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
6171                 ok(hr == S_OK, "ret %08x\n", hr );
6172
6173                 hr = IXMLDOMComment_get_text(pComment, &str);
6174                 ok(hr == S_OK, "ret %08x\n", hr );
6175                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6176                 SysFreeString(str);
6177
6178                 /* test insertData */
6179                 str = SysAllocStringLen(NULL, 0);
6180                 hr = IXMLDOMComment_insertData(pComment, -1, str);
6181                 ok(hr == S_OK, "ret %08x\n", hr );
6182
6183                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
6184                 ok(hr == S_OK, "ret %08x\n", hr );
6185
6186                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
6187                 ok(hr == S_OK, "ret %08x\n", hr );
6188
6189                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
6190                 ok(hr == S_OK, "ret %08x\n", hr );
6191
6192                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
6193                 ok(hr == S_OK, "ret %08x\n", hr );
6194
6195                 hr = IXMLDOMComment_insertData(pComment, 0, str);
6196                 ok(hr == S_OK, "ret %08x\n", hr );
6197                 SysFreeString(str);
6198
6199                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
6200                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6201
6202                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
6203                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6204
6205                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
6206                 ok(hr == S_OK, "ret %08x\n", hr );
6207
6208                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
6209                 ok(hr == S_OK, "ret %08x\n", hr );
6210
6211                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
6212                 ok(hr == S_OK, "ret %08x\n", hr );
6213
6214                 hr = IXMLDOMComment_get_text(pComment, &str);
6215                 ok(hr == S_OK, "ret %08x\n", hr );
6216                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6217                 SysFreeString(str);
6218
6219                 /* delete data */
6220                 /* invalid arguments */
6221                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6222                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6223
6224                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6225                 ok(hr == S_OK, "ret %08x\n", hr );
6226
6227                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6228                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6229
6230                 hr = IXMLDOMComment_get_length(pComment, &len);
6231                 ok(hr == S_OK, "ret %08x\n", hr );
6232                 ok(len == 43, "expected 43 got %d\n", len);
6233
6234                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6235                 ok(hr == S_OK, "ret %08x\n", hr );
6236
6237                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6238                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6239
6240                 /* delete from start */
6241                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6242                 ok(hr == S_OK, "ret %08x\n", hr );
6243
6244                 hr = IXMLDOMComment_get_length(pComment, &len);
6245                 ok(hr == S_OK, "ret %08x\n", hr );
6246                 ok(len == 38, "expected 38 got %d\n", len);
6247
6248                 hr = IXMLDOMComment_get_text(pComment, &str);
6249                 ok(hr == S_OK, "ret %08x\n", hr );
6250                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6251                 SysFreeString(str);
6252
6253                 /* delete from end */
6254                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6255                 ok(hr == S_OK, "ret %08x\n", hr );
6256
6257                 hr = IXMLDOMComment_get_length(pComment, &len);
6258                 ok(hr == S_OK, "ret %08x\n", hr );
6259                 ok(len == 35, "expected 35 got %d\n", len);
6260
6261                 hr = IXMLDOMComment_get_text(pComment, &str);
6262                 ok(hr == S_OK, "ret %08x\n", hr );
6263                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6264                 SysFreeString(str);
6265
6266                 /* delete from inside */
6267                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6268                 ok(hr == S_OK, "ret %08x\n", hr );
6269
6270                 hr = IXMLDOMComment_get_length(pComment, &len);
6271                 ok(hr == S_OK, "ret %08x\n", hr );
6272                 ok(len == 2, "expected 2 got %d\n", len);
6273
6274                 hr = IXMLDOMComment_get_text(pComment, &str);
6275                 ok(hr == S_OK, "ret %08x\n", hr );
6276                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6277                 SysFreeString(str);
6278
6279                 /* delete whole data ... */
6280                 hr = IXMLDOMComment_get_length(pComment, &len);
6281                 ok(hr == S_OK, "ret %08x\n", hr );
6282
6283                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6284                 ok(hr == S_OK, "ret %08x\n", hr );
6285                 /* ... and try again with empty string */
6286                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6287                 ok(hr == S_OK, "ret %08x\n", hr );
6288
6289                 /* ::replaceData() */
6290                 V_VT(&v) = VT_BSTR;
6291                 V_BSTR(&v) = SysAllocString(szstr1);
6292                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6293                 ok(hr == S_OK, "ret %08x\n", hr );
6294                 VariantClear(&v);
6295
6296                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6297                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6298                 hr = IXMLDOMComment_get_text(pComment, &str);
6299                 ok(hr == S_OK, "ret %08x\n", hr );
6300                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6301                 SysFreeString(str);
6302
6303                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6304                 ok(hr == S_OK, "ret %08x\n", hr );
6305                 hr = IXMLDOMComment_get_text(pComment, &str);
6306                 ok(hr == S_OK, "ret %08x\n", hr );
6307                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6308                 SysFreeString(str);
6309
6310                 /* NULL pointer means delete */
6311                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6312                 ok(hr == S_OK, "ret %08x\n", hr );
6313                 hr = IXMLDOMComment_get_text(pComment, &str);
6314                 ok(hr == S_OK, "ret %08x\n", hr );
6315                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6316                 SysFreeString(str);
6317
6318                 /* empty string means delete */
6319                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6320                 ok(hr == S_OK, "ret %08x\n", hr );
6321                 hr = IXMLDOMComment_get_text(pComment, &str);
6322                 ok(hr == S_OK, "ret %08x\n", hr );
6323                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6324                 SysFreeString(str);
6325
6326                 /* zero count means insert */
6327                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6328                 ok(hr == S_OK, "ret %08x\n", hr );
6329                 hr = IXMLDOMComment_get_text(pComment, &str);
6330                 ok(hr == S_OK, "ret %08x\n", hr );
6331                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6332                 SysFreeString(str);
6333
6334                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6335                 ok(hr == S_OK, "ret %08x\n", hr );
6336
6337                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6338                 ok(hr == S_OK, "ret %08x\n", hr );
6339                 hr = IXMLDOMComment_get_text(pComment, &str);
6340                 ok(hr == S_OK, "ret %08x\n", hr );
6341                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6342                 SysFreeString(str);
6343
6344                 /* nonempty string, count greater than its length */
6345                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6346                 ok(hr == S_OK, "ret %08x\n", hr );
6347                 hr = IXMLDOMComment_get_text(pComment, &str);
6348                 ok(hr == S_OK, "ret %08x\n", hr );
6349                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6350                 SysFreeString(str);
6351
6352                 /* nonempty string, count less than its length */
6353                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6354                 ok(hr == S_OK, "ret %08x\n", hr );
6355                 hr = IXMLDOMComment_get_text(pComment, &str);
6356                 ok(hr == S_OK, "ret %08x\n", hr );
6357                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6358                 SysFreeString(str);
6359
6360                 IXMLDOMComment_Release(pComment);
6361             }
6362
6363             /* Element */
6364             str = SysAllocString(szElement);
6365             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6366             SysFreeString(str);
6367             ok(hr == S_OK, "ret %08x\n", hr );
6368             if(hr == S_OK)
6369             {
6370                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6371                 ok(hr == S_OK, "ret %08x\n", hr );
6372
6373                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6374                 ok(hr == S_OK, "ret %08x\n", hr );
6375                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6376                 SysFreeString(str);
6377
6378                 hr = IXMLDOMElement_get_xml(pElement, &str);
6379                 ok(hr == S_OK, "ret %08x\n", hr );
6380                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6381                 SysFreeString(str);
6382
6383                 /* Attribute */
6384                 pAttribute = (IXMLDOMAttribute*)0x1;
6385                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6386                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6387                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6388
6389                 pAttribute = (IXMLDOMAttribute*)0x1;
6390                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6391                 ok(hr == E_FAIL, "ret %08x\n", hr );
6392                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6393
6394                 str = SysAllocString(szAttribute);
6395                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6396                 SysFreeString(str);
6397                 ok(hr == S_OK, "ret %08x\n", hr );
6398                 if(hr == S_OK)
6399                 {
6400                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6401
6402                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6403                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6404
6405                     pNextChild = (IXMLDOMNode *)0x1;
6406                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6407                     ok(hr == S_FALSE, "ret %08x\n", hr );
6408                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6409
6410                     /* test Previous Sibling*/
6411                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6412                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6413
6414                     pNextChild = (IXMLDOMNode *)0x1;
6415                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6416                     ok(hr == S_FALSE, "ret %08x\n", hr );
6417                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6418
6419                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6420                     ok(hr == E_FAIL, "ret %08x\n", hr );
6421                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6422
6423                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6424                     ok(hr == S_OK, "ret %08x\n", hr );
6425                     if ( hr == S_OK )
6426                     {
6427                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6428                         ok(hr == S_OK, "ret %08x\n", hr );
6429
6430                         IXMLDOMNamedNodeMap_Release(pAttribs);
6431                     }
6432
6433                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6434                     ok(hr == S_OK, "ret %08x\n", hr );
6435                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6436                     SysFreeString(str);
6437
6438                     /* test nodeName */
6439                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6440                     ok(hr == S_OK, "ret %08x\n", hr );
6441                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6442                     SysFreeString(str);
6443
6444                     /* test name property */
6445                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6446                     ok(hr == S_OK, "ret %08x\n", hr );
6447                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6448                     SysFreeString(str);
6449
6450                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6451                     ok(hr == S_OK, "ret %08x\n", hr );
6452                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6453                     SysFreeString(str);
6454
6455                     IXMLDOMAttribute_Release(pAttribute);
6456
6457                     /* Check Element again with the Add Attribute*/
6458                     hr = IXMLDOMElement_get_xml(pElement, &str);
6459                     ok(hr == S_OK, "ret %08x\n", hr );
6460                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6461                     SysFreeString(str);
6462                 }
6463
6464                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6465                 ok(hr == S_OK, "ret %08x\n", hr );
6466
6467                 hr = IXMLDOMElement_get_xml(pElement, &str);
6468                 ok(hr == S_OK, "ret %08x\n", hr );
6469                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6470                 SysFreeString(str);
6471
6472                 /* Test for reversible escaping */
6473                 str = SysAllocString( szStrangeChars );
6474                 hr = IXMLDOMElement_put_text(pElement, str);
6475                 ok(hr == S_OK, "ret %08x\n", hr );
6476                 SysFreeString( str );
6477
6478                 hr = IXMLDOMElement_get_xml(pElement, &str);
6479                 ok(hr == S_OK, "ret %08x\n", hr );
6480                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6481                 SysFreeString(str);
6482
6483                 hr = IXMLDOMElement_get_text(pElement, &str);
6484                 ok(hr == S_OK, "ret %08x\n", hr );
6485                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6486                 SysFreeString(str);
6487
6488                 IXMLDOMElement_Release(pElement);
6489             }
6490
6491             /* CData Section */
6492             str = SysAllocString(szCData);
6493             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6494             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6495
6496             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6497             SysFreeString(str);
6498             ok(hr == S_OK, "ret %08x\n", hr );
6499             if(hr == S_OK)
6500             {
6501                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6502                 VARIANT var;
6503
6504                 VariantInit(&var);
6505
6506                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6507                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6508
6509                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6510                 ok(hr == S_OK, "ret %08x\n", hr );
6511
6512                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6513                 ok(hr == S_OK, "ret %08x\n", hr );
6514                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6515                 SysFreeString(str);
6516
6517                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6518                 ok(hr == S_OK, "ret %08x\n", hr );
6519                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6520                 SysFreeString(str);
6521
6522                 /* test lastChild */
6523                 pNextChild = (IXMLDOMNode*)0x1;
6524                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6525                 ok(hr == S_FALSE, "ret %08x\n", hr );
6526                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6527
6528                 /* put data Tests */
6529                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6530                 ok(hr == S_OK, "ret %08x\n", hr );
6531
6532                 /* Confirm XML text is good */
6533                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6534                 ok(hr == S_OK, "ret %08x\n", hr );
6535                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6536                 SysFreeString(str);
6537
6538                 /* Confirm we get the put_data Text back */
6539                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6540                 ok(hr == S_OK, "ret %08x\n", hr );
6541                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6542                 SysFreeString(str);
6543
6544                 /* test length property */
6545                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6546                 ok(hr == S_OK, "ret %08x\n", hr );
6547                 ok(len == 21, "expected 21 got %d\n", len);
6548
6549                 /* test get data */
6550                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6551                 ok(hr == S_OK, "ret %08x\n", hr );
6552                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6553                 SysFreeString(str);
6554
6555                 /* test substringData */
6556                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6557                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6558
6559                 /* test substringData - Invalid offset */
6560                 str = (BSTR)&szElement;
6561                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6562                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6563                 ok( str == NULL, "incorrect string\n");
6564
6565                 /* test substringData - Invalid offset */
6566                 str = (BSTR)&szElement;
6567                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6568                 ok(hr == S_FALSE, "ret %08x\n", hr );
6569                 ok( str == NULL, "incorrect string\n");
6570
6571                 /* test substringData - Invalid size */
6572                 str = (BSTR)&szElement;
6573                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6574                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6575                 ok( str == NULL, "incorrect string\n");
6576
6577                 /* test substringData - Invalid size */
6578                 str = (BSTR)&szElement;
6579                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6580                 ok(hr == S_FALSE, "ret %08x\n", hr );
6581                 ok( str == NULL, "incorrect string\n");
6582
6583                 /* test substringData - Start of string */
6584                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6585                 ok(hr == S_OK, "ret %08x\n", hr );
6586                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6587                 SysFreeString(str);
6588
6589                 /* test substringData - Middle of string */
6590                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6591                 ok(hr == S_OK, "ret %08x\n", hr );
6592                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6593                 SysFreeString(str);
6594
6595                 /* test substringData - End of string */
6596                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6597                 ok(hr == S_OK, "ret %08x\n", hr );
6598                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6599                 SysFreeString(str);
6600
6601                 /* test appendData */
6602                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6603                 ok(hr == S_OK, "ret %08x\n", hr );
6604
6605                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6606                 ok(hr == S_OK, "ret %08x\n", hr );
6607
6608                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6609                 ok(hr == S_OK, "ret %08x\n", hr );
6610
6611                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6612                 ok(hr == S_OK, "ret %08x\n", hr );
6613                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6614                 SysFreeString(str);
6615
6616                 /* test insertData */
6617                 str = SysAllocStringLen(NULL, 0);
6618                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6619                 ok(hr == S_OK, "ret %08x\n", hr );
6620
6621                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6622                 ok(hr == S_OK, "ret %08x\n", hr );
6623
6624                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6625                 ok(hr == S_OK, "ret %08x\n", hr );
6626
6627                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6628                 ok(hr == S_OK, "ret %08x\n", hr );
6629
6630                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6631                 ok(hr == S_OK, "ret %08x\n", hr );
6632
6633                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6634                 ok(hr == S_OK, "ret %08x\n", hr );
6635                 SysFreeString(str);
6636
6637                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6638                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6639
6640                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6641                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6642
6643                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6644                 ok(hr == S_OK, "ret %08x\n", hr );
6645
6646                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6647                 ok(hr == S_OK, "ret %08x\n", hr );
6648
6649                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6650                 ok(hr == S_OK, "ret %08x\n", hr );
6651
6652                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6653                 ok(hr == S_OK, "ret %08x\n", hr );
6654                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6655                 SysFreeString(str);
6656
6657                 /* delete data */
6658                 /* invalid arguments */
6659                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6660                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6661
6662                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6663                 ok(hr == S_OK, "ret %08x\n", hr );
6664
6665                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6666                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6667
6668                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6669                 ok(hr == S_OK, "ret %08x\n", hr );
6670                 ok(len == 43, "expected 43 got %d\n", len);
6671
6672                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6673                 ok(hr == S_OK, "ret %08x\n", hr );
6674
6675                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6676                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6677
6678                 /* delete from start */
6679                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6680                 ok(hr == S_OK, "ret %08x\n", hr );
6681
6682                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6683                 ok(hr == S_OK, "ret %08x\n", hr );
6684                 ok(len == 38, "expected 38 got %d\n", len);
6685
6686                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6687                 ok(hr == S_OK, "ret %08x\n", hr );
6688                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6689                 SysFreeString(str);
6690
6691                 /* delete from end */
6692                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6693                 ok(hr == S_OK, "ret %08x\n", hr );
6694
6695                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6696                 ok(hr == S_OK, "ret %08x\n", hr );
6697                 ok(len == 35, "expected 35 got %d\n", len);
6698
6699                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6700                 ok(hr == S_OK, "ret %08x\n", hr );
6701                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6702                 SysFreeString(str);
6703
6704                 /* delete from inside */
6705                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6706                 ok(hr == S_OK, "ret %08x\n", hr );
6707
6708                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6709                 ok(hr == S_OK, "ret %08x\n", hr );
6710                 ok(len == 2, "expected 2 got %d\n", len);
6711
6712                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6713                 ok(hr == S_OK, "ret %08x\n", hr );
6714                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6715                 SysFreeString(str);
6716
6717                 /* delete whole data ... */
6718                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6719                 ok(hr == S_OK, "ret %08x\n", hr );
6720
6721                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6722                 ok(hr == S_OK, "ret %08x\n", hr );
6723
6724                 /* ... and try again with empty string */
6725                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6726                 ok(hr == S_OK, "ret %08x\n", hr );
6727
6728                 /* ::replaceData() */
6729                 V_VT(&v) = VT_BSTR;
6730                 V_BSTR(&v) = SysAllocString(szstr1);
6731                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6732                 ok(hr == S_OK, "ret %08x\n", hr );
6733                 VariantClear(&v);
6734
6735                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6736                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6737                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6738                 ok(hr == S_OK, "ret %08x\n", hr );
6739                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6740                 SysFreeString(str);
6741
6742                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6743                 ok(hr == S_OK, "ret %08x\n", hr );
6744                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6745                 ok(hr == S_OK, "ret %08x\n", hr );
6746                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6747                 SysFreeString(str);
6748
6749                 /* NULL pointer means delete */
6750                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6751                 ok(hr == S_OK, "ret %08x\n", hr );
6752                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6753                 ok(hr == S_OK, "ret %08x\n", hr );
6754                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6755                 SysFreeString(str);
6756
6757                 /* empty string means delete */
6758                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6759                 ok(hr == S_OK, "ret %08x\n", hr );
6760                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6761                 ok(hr == S_OK, "ret %08x\n", hr );
6762                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6763                 SysFreeString(str);
6764
6765                 /* zero count means insert */
6766                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6767                 ok(hr == S_OK, "ret %08x\n", hr );
6768                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6769                 ok(hr == S_OK, "ret %08x\n", hr );
6770                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6771                 SysFreeString(str);
6772
6773                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6774                 ok(hr == S_OK, "ret %08x\n", hr );
6775
6776                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6777                 ok(hr == S_OK, "ret %08x\n", hr );
6778                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6779                 ok(hr == S_OK, "ret %08x\n", hr );
6780                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6781                 SysFreeString(str);
6782
6783                 /* nonempty string, count greater than its length */
6784                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6785                 ok(hr == S_OK, "ret %08x\n", hr );
6786                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6787                 ok(hr == S_OK, "ret %08x\n", hr );
6788                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6789                 SysFreeString(str);
6790
6791                 /* nonempty string, count less than its length */
6792                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6793                 ok(hr == S_OK, "ret %08x\n", hr );
6794                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6795                 ok(hr == S_OK, "ret %08x\n", hr );
6796                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6797                 SysFreeString(str);
6798
6799                 IXMLDOMCDATASection_Release(pCDataSec);
6800             }
6801
6802             /* Document Fragments */
6803             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6804             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6805
6806             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6807             ok(hr == S_OK, "ret %08x\n", hr );
6808             if(hr == S_OK)
6809             {
6810                 IXMLDOMNode *node;
6811
6812                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6813                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6814
6815                 node = (IXMLDOMNode *)0x1;
6816                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6817                 ok(hr == S_FALSE, "ret %08x\n", hr );
6818                 ok(node == NULL, "expected NULL, got %p\n", node);
6819
6820                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6821                 ok(hr == S_OK, "ret %08x\n", hr );
6822
6823                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6824                 ok(hr == S_OK, "ret %08x\n", hr );
6825                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6826                 SysFreeString(str);
6827
6828                 /* test next Sibling*/
6829                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6830                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6831
6832                 node = (IXMLDOMNode *)0x1;
6833                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6834                 ok(hr == S_FALSE, "ret %08x\n", hr );
6835                 ok(node == NULL, "next sibling not NULL\n");
6836
6837                 /* test Previous Sibling*/
6838                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6839                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6840
6841                 node = (IXMLDOMNode *)0x1;
6842                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6843                 ok(hr == S_FALSE, "ret %08x\n", hr );
6844                 ok(node == NULL, "previous sibling not NULL\n");
6845
6846                 IXMLDOMDocumentFragment_Release(pDocFrag);
6847             }
6848
6849             /* Entity References */
6850             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6851             ok(hr == E_FAIL, "ret %08x\n", hr );
6852             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6853             ok(hr == E_FAIL, "ret %08x\n", hr );
6854
6855             str = SysAllocString(szEntityRef);
6856             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6857             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6858
6859             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6860             SysFreeString(str);
6861             ok(hr == S_OK, "ret %08x\n", hr );
6862             if(hr == S_OK)
6863             {
6864                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6865                 ok(hr == S_OK, "ret %08x\n", hr );
6866
6867                 /* test get_xml*/
6868                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6869                 ok(hr == S_OK, "ret %08x\n", hr );
6870                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6871                 SysFreeString(str);
6872
6873                 IXMLDOMEntityReference_Release(pEntityRef);
6874             }
6875
6876             IXMLDOMElement_Release( pRoot );
6877         }
6878     }
6879
6880     IXMLDOMDocument_Release(doc);
6881
6882     free_bstrs();
6883 }
6884
6885 typedef struct {
6886     const char *name;
6887     const char *type;
6888     HRESULT hr;
6889 } put_datatype_t;
6890
6891 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6892    So many of the names have been changed to reflect this. */
6893 static put_datatype_t put_datatype_data[] = {
6894     { "test_inval",      "abcdefg",     E_FAIL },
6895     { "test_bool",       "Boolean",     S_OK },
6896     { "test_string",     "String",      S_OK },
6897     { "test_number",     "number",      S_OK },
6898     { "test_int",        "InT",         S_OK },
6899     { "test_fixed",      "fixed.14.4",  S_OK },
6900     { "test_datetime",   "DateTime",    S_OK },
6901     { "test_datetimetz", "DateTime.tz", S_OK },
6902     { "test_date",       "Date",        S_OK },
6903     { "test_time",       "Time",        S_OK },
6904     { "test_timetz",     "Time.tz",     S_OK },
6905     { "test_I1",         "I1",          S_OK },
6906     { "test_I2",         "I2",          S_OK },
6907     { "test_I4",         "I4",          S_OK },
6908     { "test_UI1",        "UI1",         S_OK },
6909     { "test_UI2",        "UI2",         S_OK },
6910     { "test_UI4",        "UI4",         S_OK },
6911     { "test_r4",         "r4",          S_OK },
6912     { "test_r8",         "r8",          S_OK },
6913     { "test_float",      "float",       S_OK },
6914     { "test_uuid",       "UuId",        S_OK },
6915     { "test_binhex",     "bin.hex",     S_OK },
6916     { "test_binbase64",  "bin.base64",  S_OK },
6917     { NULL }
6918 };
6919
6920 typedef struct {
6921     DOMNodeType type;
6922     HRESULT hr;
6923 } put_datatype_notype_t;
6924
6925 static put_datatype_notype_t put_dt_notype[] = {
6926     { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6927     { NODE_DOCUMENT_FRAGMENT,      E_FAIL },
6928     { NODE_ENTITY_REFERENCE,       E_FAIL },
6929     { NODE_CDATA_SECTION,          E_FAIL },
6930     { NODE_COMMENT,                E_FAIL },
6931     { NODE_INVALID }
6932 };
6933
6934 static void test_put_dataType( void )
6935 {
6936     const put_datatype_notype_t *ptr2 = put_dt_notype;
6937     const put_datatype_t *ptr = put_datatype_data;
6938     IXMLDOMElement *root, *element;
6939     BSTR nameW, type1W, type2W;
6940     IXMLDOMDocument *doc;
6941     HRESULT hr;
6942
6943     doc = create_document(&IID_IXMLDOMDocument);
6944     if (!doc) return;
6945
6946     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6947     EXPECT_HR(hr, E_INVALIDARG);
6948
6949     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6950     EXPECT_HR(hr, S_OK);
6951
6952     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6953     EXPECT_HR(hr, S_OK);
6954
6955     hr = IXMLDOMElement_put_dataType(root, NULL);
6956     EXPECT_HR(hr, E_INVALIDARG);
6957
6958     while (ptr->name)
6959     {
6960         hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6961         EXPECT_HR(hr, S_OK);
6962         if(hr == S_OK)
6963         {
6964             hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6965             EXPECT_HR(hr, S_OK);
6966
6967             hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6968             ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6969
6970             IXMLDOMElement_Release(element);
6971         }
6972         ptr++;
6973     }
6974
6975     /* check changing types */
6976     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6977     EXPECT_HR(hr, S_OK);
6978
6979     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6980     EXPECT_HR(hr, S_OK);
6981
6982     hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6983     EXPECT_HR(hr, S_OK);
6984
6985     hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6986     EXPECT_HR(hr, S_OK);
6987
6988     IXMLDOMElement_Release(element);
6989
6990     /* try to set type for node without a type */
6991     nameW  = _bstr_("testname");
6992     type1W = _bstr_("string");
6993     type2W = _bstr_("number");
6994     while (ptr2->type != NODE_INVALID)
6995     {
6996         IXMLDOMNode *node;
6997         VARIANT type;
6998
6999         V_VT(&type) = VT_I2;
7000         V_I2(&type) = ptr2->type;
7001
7002         hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
7003         EXPECT_HR(hr, S_OK);
7004         if(hr == S_OK)
7005         {
7006             hr = IXMLDOMElement_appendChild(root, node, NULL);
7007             EXPECT_HR(hr, S_OK);
7008
7009             hr = IXMLDOMNode_put_dataType(node, NULL);
7010             EXPECT_HR(hr, E_INVALIDARG);
7011
7012             hr = IXMLDOMNode_put_dataType(node, type1W);
7013             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7014             hr = IXMLDOMNode_put_dataType(node, type2W);
7015             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7016
7017             IXMLDOMNode_Release(node);
7018         }
7019         ptr2++;
7020     }
7021
7022     IXMLDOMElement_Release(root);
7023     IXMLDOMDocument_Release(doc);
7024     free_bstrs();
7025 }
7026
7027 static void test_save(void)
7028 {
7029     IXMLDOMDocument *doc, *doc2;
7030     IXMLDOMElement *root;
7031     VARIANT file, vDoc;
7032     BSTR sOrig, sNew, filename;
7033     char buffer[100];
7034     DWORD read = 0;
7035     HANDLE hfile;
7036     HRESULT hr;
7037
7038     doc = create_document(&IID_IXMLDOMDocument);
7039     if (!doc) return;
7040
7041     doc2 = create_document(&IID_IXMLDOMDocument);
7042     if (!doc2)
7043     {
7044         IXMLDOMDocument_Release(doc);
7045         return;
7046     }
7047
7048     /* save to IXMLDOMDocument */
7049     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7050     EXPECT_HR(hr, S_OK);
7051
7052     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7053     EXPECT_HR(hr, S_OK);
7054
7055     V_VT(&vDoc) = VT_UNKNOWN;
7056     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
7057
7058     hr = IXMLDOMDocument_save(doc, vDoc);
7059     EXPECT_HR(hr, S_OK);
7060
7061     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7062     EXPECT_HR(hr, S_OK);
7063
7064     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7065     EXPECT_HR(hr, S_OK);
7066
7067     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7068
7069     SysFreeString(sOrig);
7070     SysFreeString(sNew);
7071
7072     IXMLDOMElement_Release(root);
7073     IXMLDOMDocument_Release(doc2);
7074
7075     /* save to path */
7076     V_VT(&file) = VT_BSTR;
7077     V_BSTR(&file) = _bstr_("test.xml");
7078
7079     hr = IXMLDOMDocument_save(doc, file);
7080     EXPECT_HR(hr, S_OK);
7081
7082     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7083     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7084     if(hfile == INVALID_HANDLE_VALUE) return;
7085
7086     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7087     ok(read != 0, "could not read file\n");
7088     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7089
7090     CloseHandle(hfile);
7091     DeleteFile("test.xml");
7092
7093     /* save to path VT_BSTR | VT_BYREF */
7094     filename = _bstr_("test.xml");
7095     V_VT(&file) = VT_BSTR | VT_BYREF;
7096     V_BSTRREF(&file) = &filename;
7097
7098     hr = IXMLDOMDocument_save(doc, file);
7099     EXPECT_HR(hr, S_OK);
7100
7101     IXMLDOMDocument_Release(doc);
7102
7103     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7104     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7105     if(hfile == INVALID_HANDLE_VALUE) return;
7106
7107     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7108     ok(read != 0, "could not read file\n");
7109     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7110
7111     CloseHandle(hfile);
7112     DeleteFile("test.xml");
7113     free_bstrs();
7114 }
7115
7116 static void test_testTransforms(void)
7117 {
7118     IXMLDOMDocument *doc, *docSS;
7119     IXMLDOMNode *pNode;
7120     VARIANT_BOOL bSucc;
7121
7122     HRESULT hr;
7123
7124     doc = create_document(&IID_IXMLDOMDocument);
7125     if (!doc) return;
7126
7127     docSS = create_document(&IID_IXMLDOMDocument);
7128     if (!docSS)
7129     {
7130         IXMLDOMDocument_Release(doc);
7131         return;
7132     }
7133
7134     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7135     ok(hr == S_OK, "ret %08x\n", hr );
7136
7137     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7138     ok(hr == S_OK, "ret %08x\n", hr );
7139
7140     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7141     ok(hr == S_OK, "ret %08x\n", hr );
7142     if(hr == S_OK)
7143     {
7144         BSTR bOut;
7145
7146         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7147         ok(hr == S_OK, "ret %08x\n", hr );
7148         if(hr == S_OK)
7149         {
7150             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7151             SysFreeString(bOut);
7152         }
7153
7154         IXMLDOMNode_Release(pNode);
7155     }
7156
7157     IXMLDOMDocument_Release(docSS);
7158     IXMLDOMDocument_Release(doc);
7159
7160     free_bstrs();
7161 }
7162
7163 static void test_namespaces(void)
7164 {
7165     static const CHAR namespaces_xmlA[] =
7166         "<?xml version=\"1.0\"?>\n"
7167         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7168         "  <XMI.content>"
7169         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7170         "  </XMI.content>"
7171         "</XMI>";
7172
7173     IXMLDOMDocument *doc;
7174     IXMLDOMElement *elem;
7175     IXMLDOMNode *node;
7176
7177     VARIANT_BOOL b;
7178     VARIANT var;
7179     HRESULT hr;
7180     BSTR str;
7181
7182     doc = create_document(&IID_IXMLDOMDocument);
7183     if (!doc) return;
7184
7185     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7186     EXPECT_HR(hr, S_OK);
7187     ok(b == VARIANT_TRUE, "got %d\n", b);
7188
7189     str = (BSTR)0xdeadbeef;
7190     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7191     EXPECT_HR(hr, S_FALSE);
7192     ok(str == NULL, "got %p\n", str);
7193
7194     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7195     EXPECT_HR(hr, S_OK);
7196     if(hr == S_OK)
7197     {
7198         IXMLDOMAttribute *attr;
7199         IXMLDOMNode *node2;
7200
7201         hr = IXMLDOMNode_get_firstChild(node, &node2);
7202         EXPECT_HR(hr, S_OK);
7203         ok(node2 != NULL, "got %p\n", node2);
7204
7205         /* Test get_prefix */
7206         hr = IXMLDOMNode_get_prefix(node2, NULL);
7207         EXPECT_HR(hr, E_INVALIDARG);
7208         /* NOTE: Need to test that arg2 gets cleared on Error. */
7209
7210         hr = IXMLDOMNode_get_prefix(node2, &str);
7211         EXPECT_HR(hr, S_OK);
7212         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7213         SysFreeString(str);
7214
7215         hr = IXMLDOMNode_get_nodeName(node2, &str);
7216         EXPECT_HR(hr, S_OK);
7217         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7218         SysFreeString(str);
7219
7220         /* Test get_namespaceURI */
7221         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7222         EXPECT_HR(hr, E_INVALIDARG);
7223         /* NOTE: Need to test that arg2 gets cleared on Error. */
7224
7225         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7226         EXPECT_HR(hr, S_OK);
7227         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7228         SysFreeString(str);
7229
7230         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7231         EXPECT_HR(hr, S_OK);
7232
7233         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7234         EXPECT_HR(hr, S_OK);
7235
7236         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7237         EXPECT_HR(hr, S_OK);
7238         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7239         SysFreeString(str);
7240
7241         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7242         EXPECT_HR(hr, S_OK);
7243         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7244         SysFreeString(str);
7245
7246         IXMLDOMAttribute_Release(attr);
7247         IXMLDOMElement_Release(elem);
7248
7249         IXMLDOMNode_Release(node2);
7250         IXMLDOMNode_Release(node);
7251     }
7252
7253     IXMLDOMDocument_Release(doc);
7254
7255     /* create on element and try to alter namespace after that */
7256     doc = create_document(&IID_IXMLDOMDocument);
7257     if (!doc) return;
7258
7259     V_VT(&var) = VT_I2;
7260     V_I2(&var) = NODE_ELEMENT;
7261
7262     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7263     EXPECT_HR(hr, S_OK);
7264
7265     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7266     EXPECT_HR(hr, S_OK);
7267
7268     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7269     EXPECT_HR(hr, S_OK);
7270
7271     V_VT(&var) = VT_BSTR;
7272     V_BSTR(&var) = _bstr_("ns/uri2");
7273
7274     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7275     EXPECT_HR(hr, E_INVALIDARG);
7276
7277     V_VT(&var) = VT_BSTR;
7278     V_BSTR(&var) = _bstr_("ns/uri");
7279
7280     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7281     EXPECT_HR(hr, S_OK);
7282
7283     hr = IXMLDOMElement_get_xml(elem, &str);
7284     EXPECT_HR(hr, S_OK);
7285     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7286     SysFreeString(str);
7287
7288     IXMLDOMElement_Release(elem);
7289     IXMLDOMDocument_Release(doc);
7290
7291     /* create on element and try to alter namespace after that */
7292     doc = create_document_version(60, &IID_IXMLDOMDocument);
7293     if (!doc) return;
7294
7295     V_VT(&var) = VT_I2;
7296     V_I2(&var) = NODE_ELEMENT;
7297
7298     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7299     EXPECT_HR(hr, S_OK);
7300
7301     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7302     EXPECT_HR(hr, S_OK);
7303
7304     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7305     EXPECT_HR(hr, S_OK);
7306
7307     /* try same prefix, different uri */
7308     V_VT(&var) = VT_BSTR;
7309     V_BSTR(&var) = _bstr_("ns/uri2");
7310
7311     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7312     EXPECT_HR(hr, E_INVALIDARG);
7313
7314     /* try same prefix and uri */
7315     V_VT(&var) = VT_BSTR;
7316     V_BSTR(&var) = _bstr_("ns/uri");
7317
7318     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7319     EXPECT_HR(hr, S_OK);
7320
7321     hr = IXMLDOMElement_get_xml(elem, &str);
7322     EXPECT_HR(hr, S_OK);
7323     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7324     SysFreeString(str);
7325
7326     IXMLDOMElement_Release(elem);
7327     IXMLDOMDocument_Release(doc);
7328
7329     free_bstrs();
7330 }
7331
7332 static void test_FormattingXML(void)
7333 {
7334     IXMLDOMDocument *doc;
7335     IXMLDOMElement *pElement;
7336     VARIANT_BOOL bSucc;
7337     HRESULT hr;
7338     BSTR str;
7339     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7340     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7341
7342     doc = create_document(&IID_IXMLDOMDocument);
7343     if (!doc) return;
7344
7345     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7346     ok(hr == S_OK, "ret %08x\n", hr );
7347     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7348
7349     if(bSucc == VARIANT_TRUE)
7350     {
7351         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7352         ok(hr == S_OK, "ret %08x\n", hr );
7353         if(hr == S_OK)
7354         {
7355             hr = IXMLDOMElement_get_xml(pElement, &str);
7356             ok(hr == S_OK, "ret %08x\n", hr );
7357             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7358             SysFreeString(str);
7359
7360             IXMLDOMElement_Release(pElement);
7361         }
7362     }
7363
7364     IXMLDOMDocument_Release(doc);
7365
7366     free_bstrs();
7367 }
7368
7369 typedef struct _nodetypedvalue_t {
7370     const char *name;
7371     VARTYPE type;
7372     const char *value; /* value in string format */
7373 } nodetypedvalue_t;
7374
7375 static const nodetypedvalue_t get_nodetypedvalue[] = {
7376     { "root/string",    VT_BSTR, "Wine" },
7377     { "root/string2",   VT_BSTR, "String" },
7378     { "root/number",    VT_BSTR, "12.44" },
7379     { "root/number2",   VT_BSTR, "-3.71e3" },
7380     { "root/int",       VT_I4,   "-13" },
7381     { "root/fixed",     VT_CY,   "7322.9371" },
7382     { "root/bool",      VT_BOOL, "-1" },
7383     { "root/datetime",  VT_DATE, "40135.14" },
7384     { "root/datetimetz",VT_DATE, "37813.59" },
7385     { "root/date",      VT_DATE, "665413" },
7386     { "root/time",      VT_DATE, "0.5813889" },
7387     { "root/timetz",    VT_DATE, "1.112512" },
7388     { "root/i1",        VT_I1,   "-13" },
7389     { "root/i2",        VT_I2,   "31915" },
7390     { "root/i4",        VT_I4,   "-312232" },
7391     { "root/ui1",       VT_UI1,  "123" },
7392     { "root/ui2",       VT_UI2,  "48282" },
7393     { "root/ui4",       VT_UI4,  "949281" },
7394     { "root/r4",        VT_R4,   "213124" },
7395     { "root/r8",        VT_R8,   "0.412" },
7396     { "root/float",     VT_R8,   "41221.421" },
7397     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7398     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7399     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7400     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7401     { 0 }
7402 };
7403
7404 static void test_nodeTypedValue(void)
7405 {
7406     const nodetypedvalue_t *entry = get_nodetypedvalue;
7407     IXMLDOMDocumentType *doctype, *doctype2;
7408     IXMLDOMProcessingInstruction *pi;
7409     IXMLDOMDocumentFragment *frag;
7410     IXMLDOMDocument *doc, *doc2;
7411     IXMLDOMCDATASection *cdata;
7412     IXMLDOMComment *comment;
7413     IXMLDOMNode *node;
7414     VARIANT_BOOL b;
7415     VARIANT value;
7416     HRESULT hr;
7417
7418     doc = create_document(&IID_IXMLDOMDocument);
7419     if (!doc) return;
7420
7421     b = VARIANT_FALSE;
7422     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7423     ok(hr == S_OK, "ret %08x\n", hr );
7424     ok(b == VARIANT_TRUE, "got %d\n", b);
7425
7426     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7427     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7428
7429     V_VT(&value) = VT_BSTR;
7430     V_BSTR(&value) = NULL;
7431     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7432     ok(hr == S_FALSE, "ret %08x\n", hr );
7433     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7434
7435     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7436     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7437
7438     V_VT(&value) = VT_EMPTY;
7439     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7440     ok(hr == S_FALSE, "ret %08x\n", hr );
7441     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7442
7443     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7444     ok(hr == S_OK, "ret %08x\n", hr );
7445
7446     V_VT(&value) = VT_BSTR;
7447     V_BSTR(&value) = NULL;
7448     hr = IXMLDOMNode_get_nodeValue(node, &value);
7449     ok(hr == S_FALSE, "ret %08x\n", hr );
7450     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7451
7452     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7453     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7454
7455     IXMLDOMNode_Release(node);
7456
7457     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7458     ok(hr == S_OK, "ret %08x\n", hr );
7459     {
7460         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7461
7462         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7463         ok(hr == S_OK, "ret %08x\n", hr );
7464         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7465         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7466         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7467             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7468         VariantClear(&value);
7469         IXMLDOMNode_Release(node);
7470     }
7471
7472     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7473     ok(hr == S_OK, "ret %08x\n", hr );
7474     {
7475         V_VT(&value) = VT_NULL;
7476         V_BSTR(&value) = (void*)0xdeadbeef;
7477         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7478         ok(hr == S_OK, "ret %08x\n", hr );
7479         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7480         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7481         IXMLDOMProcessingInstruction_Release(pi);
7482         VariantClear(&value);
7483     }
7484
7485     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7486     ok(hr == S_OK, "ret %08x\n", hr );
7487     {
7488         V_VT(&value) = VT_NULL;
7489         V_BSTR(&value) = (void*)0xdeadbeef;
7490         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7491         ok(hr == S_OK, "ret %08x\n", hr );
7492         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7493         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7494         IXMLDOMCDATASection_Release(cdata);
7495         VariantClear(&value);
7496     }
7497
7498     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7499     ok(hr == S_OK, "ret %08x\n", hr );
7500     {
7501         V_VT(&value) = VT_NULL;
7502         V_BSTR(&value) = (void*)0xdeadbeef;
7503         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7504         ok(hr == S_OK, "ret %08x\n", hr );
7505         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7506         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7507         IXMLDOMComment_Release(comment);
7508         VariantClear(&value);
7509     }
7510
7511     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7512     ok(hr == S_OK, "ret %08x\n", hr );
7513     {
7514         V_VT(&value) = VT_EMPTY;
7515         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7516         ok(hr == S_FALSE, "ret %08x\n", hr );
7517         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7518         IXMLDOMDocumentFragment_Release(frag);
7519     }
7520
7521     doc2 = create_document(&IID_IXMLDOMDocument);
7522
7523     b = VARIANT_FALSE;
7524     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7525     ok(hr == S_OK, "ret %08x\n", hr );
7526     ok(b == VARIANT_TRUE, "got %d\n", b);
7527
7528     EXPECT_REF(doc2, 1);
7529
7530     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7531     ok(hr == S_OK, "ret %08x\n", hr );
7532
7533     EXPECT_REF(doc2, 1);
7534     todo_wine EXPECT_REF(doctype, 2);
7535
7536     {
7537         V_VT(&value) = VT_EMPTY;
7538         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7539         ok(hr == S_FALSE, "ret %08x\n", hr );
7540         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7541     }
7542
7543     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7544     ok(hr == S_OK, "ret %08x\n", hr );
7545     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7546
7547     IXMLDOMDocumentType_Release(doctype2);
7548     IXMLDOMDocumentType_Release(doctype);
7549
7550     IXMLDOMDocument_Release(doc2);
7551
7552     while (entry->name)
7553     {
7554         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7555         ok(hr == S_OK, "ret %08x\n", hr );
7556
7557         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7558         ok(hr == S_OK, "ret %08x\n", hr );
7559         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7560
7561         if (entry->type == (VT_ARRAY|VT_UI1))
7562         {
7563             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7564                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7565         }
7566
7567         if (entry->type != VT_BSTR)
7568         {
7569            if (entry->type == VT_DATE ||
7570                entry->type == VT_R8 ||
7571                entry->type == VT_CY)
7572            {
7573                if (entry->type == VT_DATE)
7574                {
7575                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7576                    ok(hr == S_OK, "ret %08x\n", hr );
7577                }
7578                hr = VariantChangeTypeEx(&value, &value,
7579                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7580                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7581                ok(hr == S_OK, "ret %08x\n", hr );
7582            }
7583            else
7584            {
7585                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7586                ok(hr == S_OK, "ret %08x\n", hr );
7587            }
7588
7589            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7590            if (entry->type == (VT_ARRAY|VT_UI1))
7591            {
7592                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7593                   "expected %s\n", entry->value);
7594            }
7595            else
7596                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7597                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7598         }
7599         else
7600            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7601                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7602
7603         VariantClear( &value );
7604         IXMLDOMNode_Release(node);
7605
7606         entry++;
7607     }
7608
7609     IXMLDOMDocument_Release(doc);
7610     free_bstrs();
7611 }
7612
7613 static void test_TransformWithLoadingLocalFile(void)
7614 {
7615     IXMLDOMDocument *doc;
7616     IXMLDOMDocument *xsl;
7617     IXMLDOMNode *pNode;
7618     VARIANT_BOOL bSucc;
7619     HRESULT hr;
7620     HANDLE file;
7621     DWORD dwWritten;
7622     char lpPathBuffer[MAX_PATH];
7623     int i;
7624
7625     /* Create a Temp File. */
7626     GetTempPathA(MAX_PATH, lpPathBuffer);
7627     strcat(lpPathBuffer, "customers.xml" );
7628
7629     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7630     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7631     if(file == INVALID_HANDLE_VALUE)
7632         return;
7633
7634     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7635     CloseHandle(file);
7636
7637     /* Correct path to not include a escape character. */
7638     for(i=0; i < strlen(lpPathBuffer); i++)
7639     {
7640         if(lpPathBuffer[i] == '\\')
7641             lpPathBuffer[i] = '/';
7642     }
7643
7644     doc = create_document(&IID_IXMLDOMDocument);
7645     if (!doc) return;
7646
7647     xsl = create_document(&IID_IXMLDOMDocument);
7648     if (!xsl)
7649     {
7650         IXMLDOMDocument2_Release(doc);
7651         return;
7652     }
7653
7654     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7655     ok(hr == S_OK, "ret %08x\n", hr );
7656     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7657     if(bSucc == VARIANT_TRUE)
7658     {
7659         BSTR sXSL;
7660         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7661         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7662         BSTR sFileName = _bstr_(lpPathBuffer);
7663         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7664
7665         sXSL = SysAllocStringLen(NULL, nLegnth);
7666         lstrcpyW(sXSL, sPart1);
7667         lstrcatW(sXSL, sFileName);
7668         lstrcatW(sXSL, sPart2);
7669
7670         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7671         ok(hr == S_OK, "ret %08x\n", hr );
7672         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7673         if(bSucc == VARIANT_TRUE)
7674         {
7675             BSTR sResult;
7676
7677             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7678             ok(hr == S_OK, "ret %08x\n", hr );
7679             if(hr == S_OK)
7680             {
7681                 /* This will load the temp file via the XSL */
7682                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7683                 ok(hr == S_OK, "ret %08x\n", hr );
7684                 if(hr == S_OK)
7685                 {
7686                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7687                     SysFreeString(sResult);
7688                 }
7689
7690                 IXMLDOMNode_Release(pNode);
7691             }
7692         }
7693
7694         SysFreeString(sXSL);
7695     }
7696
7697     IXMLDOMDocument_Release(doc);
7698     IXMLDOMDocument_Release(xsl);
7699
7700     DeleteFile(lpPathBuffer);
7701     free_bstrs();
7702 }
7703
7704 static void test_put_nodeValue(void)
7705 {
7706     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7707     IXMLDOMDocument *doc;
7708     IXMLDOMText *text;
7709     IXMLDOMEntityReference *entityref;
7710     IXMLDOMAttribute *attr;
7711     IXMLDOMNode *node;
7712     HRESULT hr;
7713     VARIANT data, type;
7714
7715     doc = create_document(&IID_IXMLDOMDocument);
7716     if (!doc) return;
7717
7718     /* test for unsupported types */
7719     /* NODE_DOCUMENT */
7720     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7721     ok(hr == S_OK, "ret %08x\n", hr );
7722     V_VT(&data) = VT_BSTR;
7723     V_BSTR(&data) = _bstr_("one two three");
7724     hr = IXMLDOMNode_put_nodeValue(node, data);
7725     ok(hr == E_FAIL, "ret %08x\n", hr );
7726     IXMLDOMNode_Release(node);
7727
7728     /* NODE_DOCUMENT_FRAGMENT */
7729     V_VT(&type) = VT_I1;
7730     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7731     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7732     ok(hr == S_OK, "ret %08x\n", hr );
7733     V_VT(&data) = VT_BSTR;
7734     V_BSTR(&data) = _bstr_("one two three");
7735     hr = IXMLDOMNode_put_nodeValue(node, data);
7736     ok(hr == E_FAIL, "ret %08x\n", hr );
7737     IXMLDOMNode_Release(node);
7738
7739     /* NODE_ELEMENT */
7740     V_VT(&type) = VT_I1;
7741     V_I1(&type) = NODE_ELEMENT;
7742     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7743     ok(hr == S_OK, "ret %08x\n", hr );
7744     V_VT(&data) = VT_BSTR;
7745     V_BSTR(&data) = _bstr_("one two three");
7746     hr = IXMLDOMNode_put_nodeValue(node, data);
7747     ok(hr == E_FAIL, "ret %08x\n", hr );
7748     IXMLDOMNode_Release(node);
7749
7750     /* NODE_ENTITY_REFERENCE */
7751     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7752     ok(hr == S_OK, "ret %08x\n", hr );
7753
7754     V_VT(&data) = VT_BSTR;
7755     V_BSTR(&data) = _bstr_("one two three");
7756     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7757     ok(hr == E_FAIL, "ret %08x\n", hr );
7758
7759     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7760     ok(hr == S_OK, "ret %08x\n", hr );
7761     V_VT(&data) = VT_BSTR;
7762     V_BSTR(&data) = _bstr_("one two three");
7763     hr = IXMLDOMNode_put_nodeValue(node, data);
7764     ok(hr == E_FAIL, "ret %08x\n", hr );
7765     IXMLDOMNode_Release(node);
7766     IXMLDOMEntityReference_Release(entityref);
7767
7768     /* supported types */
7769     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7770     ok(hr == S_OK, "ret %08x\n", hr );
7771     V_VT(&data) = VT_BSTR;
7772     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7773     hr = IXMLDOMText_put_nodeValue(text, data);
7774     ok(hr == S_OK, "ret %08x\n", hr );
7775     IXMLDOMText_Release(text);
7776
7777     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7778     ok(hr == S_OK, "ret %08x\n", hr );
7779     V_VT(&data) = VT_BSTR;
7780     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7781     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7782     ok(hr == S_OK, "ret %08x\n", hr );
7783     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7784     ok(hr == S_OK, "ret %08x\n", hr );
7785     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7786         wine_dbgstr_w(V_BSTR(&data)));
7787     VariantClear(&data);
7788     IXMLDOMAttribute_Release(attr);
7789
7790     free_bstrs();
7791
7792     IXMLDOMDocument_Release(doc);
7793 }
7794
7795 static void test_document_IObjectSafety(void)
7796 {
7797     IXMLDOMDocument *doc;
7798     IObjectSafety *safety;
7799     HRESULT hr;
7800
7801     doc = create_document(&IID_IXMLDOMDocument);
7802     if (!doc) return;
7803
7804     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7805     ok(hr == S_OK, "ret %08x\n", hr );
7806
7807     test_IObjectSafety_common(safety);
7808
7809     IObjectSafety_Release(safety);
7810
7811     IXMLDOMDocument_Release(doc);
7812 }
7813
7814 typedef struct _property_test_t {
7815     const GUID *guid;
7816     const char *clsid;
7817     const char *property;
7818     const char *value;
7819 } property_test_t;
7820
7821 static const property_test_t properties_test_data[] = {
7822     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7823     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7824     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7825     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7826     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7827     { 0 }
7828 };
7829
7830 static void test_default_properties(void)
7831 {
7832     const property_test_t *entry = properties_test_data;
7833
7834     while (entry->guid)
7835     {
7836         IXMLDOMDocument2 *doc;
7837         VARIANT var;
7838         HRESULT hr;
7839
7840         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7841         if (hr != S_OK)
7842         {
7843             win_skip("can't create %s instance\n", entry->clsid);
7844             entry++;
7845             continue;
7846         }
7847
7848         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7849         ok(hr == S_OK, "got 0x%08x\n", hr);
7850         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7851            entry->value, entry->clsid);
7852         VariantClear(&var);
7853
7854         IXMLDOMDocument2_Release(doc);
7855
7856         entry++;
7857     }
7858 }
7859
7860 typedef struct {
7861     const char *query;
7862     const char *list;
7863 } xslpattern_test_t;
7864
7865 static const xslpattern_test_t xslpattern_test[] = {
7866     { "root//elem[0]", "E1.E2.D1" },
7867     { "root//elem[index()=1]", "E2.E2.D1" },
7868     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7869     { "root//elem[end()]", "E4.E2.D1" },
7870     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7871     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7872     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7873     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7874     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7875     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7876     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7877     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7878     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7879     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7880     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7881     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7882     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7883     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7884     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7885     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7886     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7887     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7888     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7889     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7890     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7891     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7892     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7893     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7894     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7895     { "root/elem[0]", "E1.E2.D1" },
7896     { "root/elem[index()=1]", "E2.E2.D1" },
7897     { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7898     { "root/elem[end()]", "E4.E2.D1" },
7899     { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7900     { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7901     { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7902     { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7903     { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7904     { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7905     { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7906     { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7907     { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7908     { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7909     { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7910     { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7911     { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7912     { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7913     { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7914     { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7915     { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7916     { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7917     { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7918     { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7919     { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7920     { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7921     { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7922     { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7923     { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7924     { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7925     { NULL }
7926 };
7927
7928 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7929     /* prefixes don't need to be registered, you may use them as they are in the doc */
7930     { "//bar:x", "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7931     /* prefixes must be explicitly specified in the name */
7932     { "//foo:elem", "" },
7933     { "//foo:c", "E3.E4.E2.D1" },
7934     { NULL }
7935 };
7936
7937 static const xslpattern_test_t xslpattern_test_func[] = {
7938     { "attribute()", "" },
7939     { "attribute('depth')", "" },
7940     { "root/attribute('depth')", "A'depth'.E3.D1" },
7941     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7942     { "//x//attribute(id)", NULL },
7943     { "//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" },
7944     { "comment()", "C2.D1" },
7945     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7946     { "element()", "E3.D1" },
7947     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7948     { "//element(a)", NULL },
7949     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7950     { "node()", "P1.D1 C2.D1 E3.D1" },
7951     { "//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" },
7952     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7953     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7954     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7955     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7956     { "pi()", "P1.D1" },
7957     { "//y/pi()", "P1.E4.E3.D1" },
7958     { "root/textnode()", "T2.E3.D1" },
7959     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7960     { NULL }
7961 };
7962
7963 static void test_XSLPattern(void)
7964 {
7965     const xslpattern_test_t *ptr = xslpattern_test;
7966     IXMLDOMDocument2 *doc;
7967     IXMLDOMNodeList *list;
7968     VARIANT_BOOL b;
7969     HRESULT hr;
7970     LONG len;
7971
7972     doc = create_document(&IID_IXMLDOMDocument2);
7973     if (!doc) return;
7974
7975     b = VARIANT_FALSE;
7976     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7977     EXPECT_HR(hr, S_OK);
7978     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7979
7980     /* switch to XSLPattern */
7981     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7982     EXPECT_HR(hr, S_OK);
7983
7984     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7985     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7986     EXPECT_HR(hr, S_OK);
7987
7988     len = 0;
7989     hr = IXMLDOMNodeList_get_length(list, &len);
7990     EXPECT_HR(hr, S_OK);
7991     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7992     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7993     IXMLDOMNodeList_Release(list);
7994
7995     while (ptr->query)
7996     {
7997         list = NULL;
7998         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7999         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8000         len = 0;
8001         hr = IXMLDOMNodeList_get_length(list, &len);
8002         ok(len != 0, "query=%s, empty list\n", ptr->query);
8003         if (len)
8004             expect_list_and_release(list, ptr->list);
8005
8006         ptr++;
8007     }
8008
8009     /* namespace handling */
8010     /* no registered namespaces */
8011     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
8012     EXPECT_HR(hr, S_OK);
8013
8014     ptr = xslpattern_test_no_ns;
8015     while (ptr->query)
8016     {
8017         list = NULL;
8018         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8019         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8020
8021         if (*ptr->list)
8022         {
8023             len = 0;
8024             hr = IXMLDOMNodeList_get_length(list, &len);
8025             EXPECT_HR(hr, S_OK);
8026             ok(len != 0, "query=%s, empty list\n", ptr->query);
8027         }
8028         else
8029         {
8030             len = 1;
8031             hr = IXMLDOMNodeList_get_length(list, &len);
8032             EXPECT_HR(hr, S_OK);
8033             ok(len == 0, "query=%s, empty list\n", ptr->query);
8034         }
8035         if (len)
8036             expect_list_and_release(list, ptr->list);
8037
8038         ptr++;
8039     }
8040
8041     /* explicitly register prefix foo */
8042     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
8043
8044     /* now we get the same behavior as XPath */
8045     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8046     EXPECT_HR(hr, S_OK);
8047     len = 0;
8048     hr = IXMLDOMNodeList_get_length(list, &len);
8049     EXPECT_HR(hr, S_OK);
8050     ok(len != 0, "expected filled list\n");
8051     if (len)
8052         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8053
8054     /* set prefix foo to some nonexistent namespace */
8055     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8056     EXPECT_HR(hr, S_OK);
8057
8058     /* the registered prefix takes precedence */
8059     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8060     EXPECT_HR(hr, S_OK);
8061     len = 0;
8062     hr = IXMLDOMNodeList_get_length(list, &len);
8063     EXPECT_HR(hr, S_OK);
8064     ok(len == 0, "expected empty list\n");
8065     IXMLDOMNodeList_Release(list);
8066
8067     IXMLDOMDocument2_Release(doc);
8068
8069     doc = create_document(&IID_IXMLDOMDocument2);
8070     if (!doc) return;
8071
8072     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8073     EXPECT_HR(hr, S_OK);
8074     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8075
8076     ptr = xslpattern_test_func;
8077     while (ptr->query)
8078     {
8079         list = NULL;
8080         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8081         if (ptr->list)
8082         {
8083             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8084             len = 0;
8085             hr = IXMLDOMNodeList_get_length(list, &len);
8086             if (*ptr->list)
8087             {
8088                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8089                 if (len)
8090                     expect_list_and_release(list, ptr->list);
8091             }
8092             else
8093                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8094         }
8095         else
8096             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8097
8098         ptr++;
8099     }
8100
8101     IXMLDOMDocument2_Release(doc);
8102     free_bstrs();
8103 }
8104
8105 static void test_splitText(void)
8106 {
8107     IXMLDOMCDATASection *cdata;
8108     IXMLDOMElement *root;
8109     IXMLDOMDocument *doc;
8110     IXMLDOMText *text, *text2;
8111     IXMLDOMNode *node;
8112     VARIANT var;
8113     VARIANT_BOOL success;
8114     LONG length;
8115     HRESULT hr;
8116
8117     doc = create_document(&IID_IXMLDOMDocument);
8118     if (!doc) return;
8119
8120     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8121     ok(hr == S_OK, "got 0x%08x\n", hr);
8122
8123     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8124     ok(hr == S_OK, "got 0x%08x\n", hr);
8125
8126     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8127     ok(hr == S_OK, "got 0x%08x\n", hr);
8128
8129     V_VT(&var) = VT_EMPTY;
8130     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8131     ok(hr == S_OK, "got 0x%08x\n", hr);
8132
8133     length = 0;
8134     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8135     ok(hr == S_OK, "got 0x%08x\n", hr);
8136     ok(length > 0, "got %d\n", length);
8137
8138     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8139     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8140
8141     text = (void*)0xdeadbeef;
8142     /* negative offset */
8143     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8144     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8145     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8146
8147     text = (void*)0xdeadbeef;
8148     /* offset outside data */
8149     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8150     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8151     ok(text == 0, "got %p\n", text);
8152
8153     text = (void*)0xdeadbeef;
8154     /* offset outside data */
8155     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8156     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8157     ok(text == 0, "got %p\n", text);
8158
8159     /* no empty node created */
8160     node = (void*)0xdeadbeef;
8161     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8162     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8163     ok(node == 0, "got %p\n", text);
8164
8165     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8166     ok(hr == S_OK, "got 0x%08x\n", hr);
8167
8168     length = 0;
8169     hr = IXMLDOMText_get_length(text, &length);
8170     ok(hr == S_OK, "got 0x%08x\n", hr);
8171     ok(length == 7, "got %d\n", length);
8172
8173     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8174     ok(hr == S_OK, "got 0x%08x\n", hr);
8175     IXMLDOMNode_Release(node);
8176
8177     /* split new text node */
8178     hr = IXMLDOMText_get_length(text, &length);
8179     ok(hr == S_OK, "got 0x%08x\n", hr);
8180
8181     node = (void*)0xdeadbeef;
8182     hr = IXMLDOMText_get_nextSibling(text, &node);
8183     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8184     ok(node == 0, "got %p\n", text);
8185
8186     hr = IXMLDOMText_splitText(text, 0, NULL);
8187     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8188
8189     text2 = (void*)0xdeadbeef;
8190     /* negative offset */
8191     hr = IXMLDOMText_splitText(text, -1, &text2);
8192     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8193     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8194
8195     text2 = (void*)0xdeadbeef;
8196     /* offset outside data */
8197     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8198     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8199     ok(text2 == 0, "got %p\n", text2);
8200
8201     text2 = (void*)0xdeadbeef;
8202     /* offset outside data */
8203     hr = IXMLDOMText_splitText(text, length, &text2);
8204     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8205     ok(text2 == 0, "got %p\n", text);
8206
8207     text2 = 0;
8208     hr = IXMLDOMText_splitText(text, 4, &text2);
8209     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8210     if (text2) IXMLDOMText_Release(text2);
8211
8212     node = 0;
8213     hr = IXMLDOMText_get_nextSibling(text, &node);
8214     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8215     if (node) IXMLDOMNode_Release(node);
8216
8217     IXMLDOMText_Release(text);
8218     IXMLDOMElement_Release(root);
8219     IXMLDOMCDATASection_Release(cdata);
8220     free_bstrs();
8221 }
8222
8223 typedef struct {
8224     const char *name;
8225     const char *uri;
8226     HRESULT hr;
8227 } ns_item_t;
8228
8229 /* default_ns_doc used */
8230 static const ns_item_t qualified_item_tests[] = {
8231     { "xml:lang", NULL, S_FALSE },
8232     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8233     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8234     { "ns:b", NULL, S_FALSE },
8235     { "ns:b", "nshref", S_FALSE },
8236     { "b", "nshref", S_OK },
8237     { "d", NULL, S_OK },
8238     { NULL }
8239 };
8240
8241 static const ns_item_t named_item_tests[] = {
8242     { "xml:lang", NULL, S_OK },
8243     { "lang", NULL, S_FALSE },
8244     { "ns:b", NULL, S_OK },
8245     { "b", NULL, S_FALSE },
8246     { "d", NULL, S_OK },
8247     { NULL }
8248 };
8249
8250 static void test_getQualifiedItem(void)
8251 {
8252     IXMLDOMNode *pr_node, *node;
8253     IXMLDOMNodeList *root_list;
8254     IXMLDOMNamedNodeMap *map;
8255     IXMLDOMElement *element;
8256     const ns_item_t* ptr;
8257     IXMLDOMDocument *doc;
8258     VARIANT_BOOL b;
8259     HRESULT hr;
8260     LONG len;
8261
8262     doc = create_document(&IID_IXMLDOMDocument);
8263     if (!doc) return;
8264
8265     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8266     EXPECT_HR(hr, S_OK);
8267     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8268
8269     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8270     EXPECT_HR(hr, S_OK);
8271
8272     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8273     EXPECT_HR(hr, S_OK);
8274
8275     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8276     EXPECT_HR(hr, S_OK);
8277     IXMLDOMNodeList_Release(root_list);
8278
8279     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8280     EXPECT_HR(hr, S_OK);
8281     IXMLDOMNode_Release(pr_node);
8282
8283     len = 0;
8284     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8285     EXPECT_HR(hr, S_OK);
8286     ok( len == 3, "length %d\n", len);
8287
8288     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8289     EXPECT_HR(hr, E_INVALIDARG);
8290
8291     node = (void*)0xdeadbeef;
8292     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8293     EXPECT_HR(hr, E_INVALIDARG);
8294     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8295
8296     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8297     EXPECT_HR(hr, E_INVALIDARG);
8298
8299     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8300     EXPECT_HR(hr, S_OK);
8301
8302     IXMLDOMNode_Release(node);
8303     IXMLDOMNamedNodeMap_Release(map);
8304     IXMLDOMElement_Release(element);
8305
8306     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8307     EXPECT_HR(hr, S_OK);
8308
8309     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8310     EXPECT_HR(hr, S_OK);
8311
8312     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8313     EXPECT_HR(hr, S_OK);
8314     IXMLDOMNode_Release(node);
8315
8316     hr = IXMLDOMElement_get_attributes(element, &map);
8317     EXPECT_HR(hr, S_OK);
8318
8319     ptr = qualified_item_tests;
8320     while (ptr->name)
8321     {
8322        node = (void*)0xdeadbeef;
8323        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8324        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8325        if (hr == S_OK)
8326            IXMLDOMNode_Release(node);
8327        else
8328            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8329        ptr++;
8330     }
8331
8332     ptr = named_item_tests;
8333     while (ptr->name)
8334     {
8335        node = (void*)0xdeadbeef;
8336        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8337        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8338        if (hr == S_OK)
8339            IXMLDOMNode_Release(node);
8340        else
8341            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8342        ptr++;
8343     }
8344
8345     IXMLDOMNamedNodeMap_Release(map);
8346
8347     IXMLDOMElement_Release(element);
8348     IXMLDOMDocument_Release(doc);
8349     free_bstrs();
8350 }
8351
8352 static void test_removeQualifiedItem(void)
8353 {
8354     IXMLDOMDocument *doc;
8355     IXMLDOMElement *element;
8356     IXMLDOMNode *pr_node, *node;
8357     IXMLDOMNodeList *root_list;
8358     IXMLDOMNamedNodeMap *map;
8359     VARIANT_BOOL b;
8360     LONG len;
8361     HRESULT hr;
8362
8363     doc = create_document(&IID_IXMLDOMDocument);
8364     if (!doc) return;
8365
8366     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8367     ok( hr == S_OK, "loadXML failed\n");
8368     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8369
8370     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8371     ok( hr == S_OK, "ret %08x\n", hr);
8372
8373     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8374     ok( hr == S_OK, "ret %08x\n", hr);
8375
8376     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8377     ok( hr == S_OK, "ret %08x\n", hr);
8378     IXMLDOMNodeList_Release(root_list);
8379
8380     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8381     ok( hr == S_OK, "ret %08x\n", hr);
8382     IXMLDOMNode_Release(pr_node);
8383
8384     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8385     ok( hr == S_OK, "ret %08x\n", hr);
8386     ok( len == 3, "length %d\n", len);
8387
8388     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8389     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8390
8391     node = (void*)0xdeadbeef;
8392     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8393     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8394     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8395
8396     /* out pointer is optional */
8397     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8398     ok( hr == S_OK, "ret %08x\n", hr);
8399
8400     /* already removed */
8401     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8402     ok( hr == S_FALSE, "ret %08x\n", hr);
8403
8404     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8405     ok( hr == S_OK, "ret %08x\n", hr);
8406     IXMLDOMNode_Release(node);
8407
8408     IXMLDOMNamedNodeMap_Release( map );
8409     IXMLDOMElement_Release( element );
8410     IXMLDOMDocument_Release( doc );
8411     free_bstrs();
8412 }
8413
8414 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8415 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8416 {
8417     VARIANT_BOOL b;
8418     VARIANT var;
8419     HRESULT hr;
8420
8421     VariantInit(&var);
8422     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8423     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8424     VariantClear(&var);
8425
8426     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8427     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8428     VariantClear(&var);
8429
8430     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8431     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8432
8433     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8434     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8435     VariantClear(&var);
8436 }
8437
8438 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8439 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8440 {
8441     VARIANT_BOOL b;
8442     VARIANT var;
8443
8444     VariantInit(&var);
8445     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8446     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8447     VariantClear(&var);
8448
8449     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8450     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8451     VariantClear(&var);
8452
8453     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8454     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8455
8456     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8457     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8458     VariantClear(&var);
8459 }
8460
8461 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8462 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8463 {
8464     VARIANT var;
8465
8466     VariantInit(&var);
8467     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8468     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8469     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8470     V_VT(&var) = VT_DISPATCH;
8471     V_DISPATCH(&var) = NULL;
8472     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8473     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8474     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8475     VariantClear(&var);
8476 }
8477
8478 #define unset_props(doc) _unset_props(__LINE__, doc)
8479 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8480 {
8481     VARIANT var;
8482
8483     VariantInit(&var);
8484     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8485     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8486     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8487     V_VT(&var) = VT_NULL;
8488     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8489     VariantClear(&var);
8490 }
8491
8492 static void test_get_ownerDocument(void)
8493 {
8494     IXMLDOMDocument *doc1, *doc2, *doc3;
8495     IXMLDOMDocument2 *doc, *doc_owner;
8496     IXMLDOMNode *node;
8497     IXMLDOMSchemaCollection *cache;
8498     VARIANT_BOOL b;
8499     VARIANT var;
8500
8501     doc = create_document(&IID_IXMLDOMDocument2);
8502     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8503     if (!doc || !cache)
8504     {
8505         if (doc) IXMLDOMDocument2_Release(doc);
8506         if (cache) IXMLDOMSchemaCollection_Release(cache);
8507         return;
8508     }
8509
8510     VariantInit(&var);
8511
8512     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8513     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8514
8515     check_default_props(doc);
8516
8517     /* set properties and check that new instances use them */
8518     set_props(doc, cache);
8519     check_set_props(doc);
8520
8521     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8522     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8523
8524     /* new interface keeps props */
8525     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8526     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8527     check_set_props(doc_owner);
8528     IXMLDOMDocument2_Release(doc_owner);
8529
8530     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8531     IXMLDOMNode_Release(node);
8532
8533     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8534
8535     /* reload */
8536     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8537     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8538
8539     /* properties retained even after reload */
8540     check_set_props(doc);
8541
8542     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8543     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8544     IXMLDOMNode_Release(node);
8545
8546     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8547     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8548     check_set_props(doc_owner);
8549
8550     /* changing properties for one instance changes them for all */
8551     unset_props(doc_owner);
8552     check_default_props(doc_owner);
8553     check_default_props(doc);
8554
8555     IXMLDOMSchemaCollection_Release(cache);
8556     IXMLDOMDocument_Release(doc1);
8557     IXMLDOMDocument_Release(doc2);
8558     IXMLDOMDocument_Release(doc3);
8559     IXMLDOMDocument2_Release(doc);
8560     IXMLDOMDocument2_Release(doc_owner);
8561     free_bstrs();
8562 }
8563
8564 static void test_setAttributeNode(void)
8565 {
8566     IXMLDOMDocument *doc, *doc2;
8567     IXMLDOMElement *elem, *elem2;
8568     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8569     VARIANT_BOOL b;
8570     HRESULT hr;
8571     VARIANT v;
8572     BSTR str;
8573     ULONG ref1, ref2;
8574
8575     doc = create_document(&IID_IXMLDOMDocument);
8576     if (!doc) return;
8577
8578     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8579     ok( hr == S_OK, "loadXML failed\n");
8580     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8581
8582     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8583     ok( hr == S_OK, "got 0x%08x\n", hr);
8584
8585     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8586     ok( hr == S_OK, "got 0x%08x\n", hr);
8587     ok( elem2 != elem, "got same instance\n");
8588
8589     ret_attr = (void*)0xdeadbeef;
8590     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8591     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8592     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8593
8594     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8595     ok( hr == S_OK, "got 0x%08x\n", hr);
8596
8597     ref1 = IXMLDOMElement_AddRef(elem);
8598     IXMLDOMElement_Release(elem);
8599
8600     ret_attr = (void*)0xdeadbeef;
8601     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8602     ok( hr == S_OK, "got 0x%08x\n", hr);
8603     ok( ret_attr == NULL, "got %p\n", ret_attr);
8604
8605     /* no reference added */
8606     ref2 = IXMLDOMElement_AddRef(elem);
8607     IXMLDOMElement_Release(elem);
8608     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8609
8610     EXPECT_CHILDREN(elem);
8611     EXPECT_CHILDREN(elem2);
8612
8613     IXMLDOMElement_Release(elem2);
8614
8615     attr2 = NULL;
8616     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8617     ok( hr == S_OK, "got 0x%08x\n", hr);
8618     ok( attr2 != attr, "got same instance %p\n", attr2);
8619     IXMLDOMAttribute_Release(attr2);
8620
8621     /* try to add it another time */
8622     ret_attr = (void*)0xdeadbeef;
8623     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8624     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8625     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8626
8627     IXMLDOMElement_Release(elem);
8628
8629     /* initially used element is released, attribute still 'has' a container */
8630     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8631     ok( hr == S_OK, "got 0x%08x\n", hr);
8632     ret_attr = (void*)0xdeadbeef;
8633     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8634     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8635     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8636     IXMLDOMElement_Release(elem);
8637
8638     /* add attribute already attached to another document */
8639     doc2 = create_document(&IID_IXMLDOMDocument);
8640
8641     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8642     ok( hr == S_OK, "loadXML failed\n");
8643     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8644
8645     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8646     ok( hr == S_OK, "got 0x%08x\n", hr);
8647     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8648     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8649     IXMLDOMElement_Release(elem);
8650
8651     IXMLDOMAttribute_Release(attr);
8652
8653     /* create element, add attribute, see if it's copied or linked */
8654     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8655     ok( hr == S_OK, "got 0x%08x\n", hr);
8656
8657     attr = NULL;
8658     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8659     ok(hr == S_OK, "got 0x%08x\n", hr);
8660     ok(attr != NULL, "got %p\n", attr);
8661
8662     ref1 = IXMLDOMAttribute_AddRef(attr);
8663     IXMLDOMAttribute_Release(attr);
8664
8665     V_VT(&v) = VT_BSTR;
8666     V_BSTR(&v) = _bstr_("attrvalue1");
8667     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8668     ok( hr == S_OK, "got 0x%08x\n", hr);
8669
8670     str = NULL;
8671     hr = IXMLDOMAttribute_get_xml(attr, &str);
8672     ok( hr == S_OK, "got 0x%08x\n", hr);
8673     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8674         "got %s\n", wine_dbgstr_w(str));
8675     SysFreeString(str);
8676
8677     ret_attr = (void*)0xdeadbeef;
8678     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8679     ok(hr == S_OK, "got 0x%08x\n", hr);
8680     ok(ret_attr == NULL, "got %p\n", ret_attr);
8681
8682     /* attribute reference increased */
8683     ref2 = IXMLDOMAttribute_AddRef(attr);
8684     IXMLDOMAttribute_Release(attr);
8685     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8686
8687     hr = IXMLDOMElement_get_xml(elem, &str);
8688     ok( hr == S_OK, "got 0x%08x\n", hr);
8689     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8690         "got %s\n", wine_dbgstr_w(str));
8691     SysFreeString(str);
8692
8693     V_VT(&v) = VT_BSTR;
8694     V_BSTR(&v) = _bstr_("attrvalue2");
8695     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8696     ok( hr == S_OK, "got 0x%08x\n", hr);
8697
8698     hr = IXMLDOMElement_get_xml(elem, &str);
8699     ok( hr == S_OK, "got 0x%08x\n", hr);
8700     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8701         "got %s\n", wine_dbgstr_w(str));
8702     SysFreeString(str);
8703
8704     IXMLDOMElement_Release(elem);
8705     IXMLDOMAttribute_Release(attr);
8706     IXMLDOMDocument_Release(doc2);
8707     IXMLDOMDocument_Release(doc);
8708     free_bstrs();
8709 }
8710
8711 static void test_createNode(void)
8712 {
8713     IXMLDOMDocument *doc;
8714     IXMLDOMElement *elem;
8715     IXMLDOMNode *node;
8716     VARIANT v, var;
8717     BSTR prefix, str;
8718     HRESULT hr;
8719     ULONG ref;
8720
8721     doc = create_document(&IID_IXMLDOMDocument);
8722     if (!doc) return;
8723
8724     EXPECT_REF(doc, 1);
8725
8726     /* reference count tests */
8727     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8728     ok( hr == S_OK, "got 0x%08x\n", hr);
8729
8730     /* initial reference is 2 */
8731 todo_wine {
8732     EXPECT_REF(elem, 2);
8733     ref = IXMLDOMElement_Release(elem);
8734     ok(ref == 1, "got %d\n", ref);
8735     /* it's released already, attempt to release now will crash it */
8736 }
8737
8738     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8739     ok( hr == S_OK, "got 0x%08x\n", hr);
8740     todo_wine EXPECT_REF(elem, 2);
8741     IXMLDOMDocument_Release(doc);
8742     todo_wine EXPECT_REF(elem, 2);
8743     IXMLDOMElement_Release(elem);
8744
8745     doc = create_document(&IID_IXMLDOMDocument);
8746
8747     /* NODE_ELEMENT nodes */
8748     /* 1. specified namespace */
8749     V_VT(&v) = VT_I4;
8750     V_I4(&v) = NODE_ELEMENT;
8751
8752     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8753     ok( hr == S_OK, "got 0x%08x\n", hr);
8754     prefix = NULL;
8755     hr = IXMLDOMNode_get_prefix(node, &prefix);
8756     ok( hr == S_OK, "got 0x%08x\n", hr);
8757     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8758     SysFreeString(prefix);
8759     IXMLDOMNode_Release(node);
8760
8761     /* 2. default namespace */
8762     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8763     ok( hr == S_OK, "got 0x%08x\n", hr);
8764     prefix = (void*)0xdeadbeef;
8765     hr = IXMLDOMNode_get_prefix(node, &prefix);
8766     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8767     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8768     /* check dump */
8769     hr = IXMLDOMNode_get_xml(node, &str);
8770     ok( hr == S_OK, "got 0x%08x\n", hr);
8771     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8772         "got %s\n", wine_dbgstr_w(str));
8773     SysFreeString(str);
8774
8775     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8776     ok( hr == S_OK, "got 0x%08x\n", hr);
8777
8778     V_VT(&var) = VT_BSTR;
8779     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8780     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8781     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8782
8783     str = NULL;
8784     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8785     ok( hr == S_OK, "got 0x%08x\n", hr);
8786     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8787     SysFreeString(str);
8788
8789     IXMLDOMElement_Release(elem);
8790     IXMLDOMNode_Release(node);
8791
8792     IXMLDOMDocument_Release(doc);
8793     free_bstrs();
8794 }
8795
8796 static const char get_prefix_doc[] =
8797     "<?xml version=\"1.0\" ?>"
8798     "<a xmlns:ns1=\"ns1 href\" />";
8799
8800 static void test_get_prefix(void)
8801 {
8802     IXMLDOMDocumentFragment *fragment;
8803     IXMLDOMCDATASection *cdata;
8804     IXMLDOMElement *element;
8805     IXMLDOMComment *comment;
8806     IXMLDOMDocument *doc;
8807     VARIANT_BOOL b;
8808     HRESULT hr;
8809     BSTR str;
8810
8811     doc = create_document(&IID_IXMLDOMDocument);
8812     if (!doc) return;
8813
8814     /* nodes that can't support prefix */
8815     /* 1. document */
8816     str = (void*)0xdeadbeef;
8817     hr = IXMLDOMDocument_get_prefix(doc, &str);
8818     EXPECT_HR(hr, S_FALSE);
8819     ok(str == NULL, "got %p\n", str);
8820
8821     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8822     EXPECT_HR(hr, E_INVALIDARG);
8823
8824     /* 2. cdata */
8825     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8826     ok(hr == S_OK, "got %08x\n", hr );
8827
8828     str = (void*)0xdeadbeef;
8829     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8830     ok(hr == S_FALSE, "got %08x\n", hr);
8831     ok( str == 0, "got %p\n", str);
8832
8833     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8834     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8835     IXMLDOMCDATASection_Release(cdata);
8836
8837     /* 3. comment */
8838     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8839     ok(hr == S_OK, "got %08x\n", hr );
8840
8841     str = (void*)0xdeadbeef;
8842     hr = IXMLDOMComment_get_prefix(comment, &str);
8843     ok(hr == S_FALSE, "got %08x\n", hr);
8844     ok( str == 0, "got %p\n", str);
8845
8846     hr = IXMLDOMComment_get_prefix(comment, NULL);
8847     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8848     IXMLDOMComment_Release(comment);
8849
8850     /* 4. fragment */
8851     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8852     ok(hr == S_OK, "got %08x\n", hr );
8853
8854     str = (void*)0xdeadbeef;
8855     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8856     ok(hr == S_FALSE, "got %08x\n", hr);
8857     ok( str == 0, "got %p\n", str);
8858
8859     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8860     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8861     IXMLDOMDocumentFragment_Release(fragment);
8862
8863     /* no prefix */
8864     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8865     ok( hr == S_OK, "got 0x%08x\n", hr);
8866
8867     hr = IXMLDOMElement_get_prefix(element, NULL);
8868     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8869
8870     str = (void*)0xdeadbeef;
8871     hr = IXMLDOMElement_get_prefix(element, &str);
8872     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8873     ok( str == 0, "got %p\n", str);
8874
8875     IXMLDOMElement_Release(element);
8876
8877     /* with prefix */
8878     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8879     ok( hr == S_OK, "got 0x%08x\n", hr);
8880
8881     str = (void*)0xdeadbeef;
8882     hr = IXMLDOMElement_get_prefix(element, &str);
8883     ok( hr == S_OK, "got 0x%08x\n", hr);
8884     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8885     SysFreeString(str);
8886
8887     str = (void*)0xdeadbeef;
8888     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8889     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8890     ok( str == 0, "got %p\n", str);
8891
8892     IXMLDOMElement_Release(element);
8893
8894     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8895     EXPECT_HR(hr, S_OK);
8896
8897     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8898     EXPECT_HR(hr, S_OK);
8899
8900     str = (void*)0xdeadbeef;
8901     hr = IXMLDOMElement_get_prefix(element, &str);
8902     EXPECT_HR(hr, S_FALSE);
8903     ok(str == NULL, "got %p\n", str);
8904
8905     str = (void*)0xdeadbeef;
8906     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8907     EXPECT_HR(hr, S_FALSE);
8908     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8909
8910     IXMLDOMDocument_Release(doc);
8911     free_bstrs();
8912 }
8913
8914 static void test_selectSingleNode(void)
8915 {
8916     IXMLDOMDocument *doc;
8917     IXMLDOMNodeList *list;
8918     IXMLDOMNode *node;
8919     VARIANT_BOOL b;
8920     HRESULT hr;
8921     LONG len;
8922
8923     doc = create_document(&IID_IXMLDOMDocument);
8924     if (!doc) return;
8925
8926     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8927     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8928
8929     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8930     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8931
8932     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8933     ok( hr == S_OK, "loadXML failed\n");
8934     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8935
8936     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8937     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8938
8939     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8940     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8941
8942     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8943     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8944
8945     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8946     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8947
8948     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8949     ok(hr == S_OK, "got 0x%08x\n", hr);
8950     IXMLDOMNode_Release(node);
8951
8952     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8953     ok(hr == S_OK, "got 0x%08x\n", hr);
8954     IXMLDOMNodeList_Release(list);
8955
8956     list = (void*)0xdeadbeef;
8957     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8958     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8959     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8960
8961     node = (void*)0xdeadbeef;
8962     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8963     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8964     ok(node == 0, "got %p\n", node);
8965
8966     list = (void*)0xdeadbeef;
8967     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8968     ok(hr == S_OK, "got 0x%08x\n", hr);
8969     len = 1;
8970     hr = IXMLDOMNodeList_get_length(list, &len);
8971     ok(hr == S_OK, "got 0x%08x\n", hr);
8972     ok(len == 0, "got %d\n", len);
8973     IXMLDOMNodeList_Release(list);
8974
8975     IXMLDOMDocument_Release(doc);
8976     free_bstrs();
8977 }
8978
8979 static void test_events(void)
8980 {
8981     IConnectionPointContainer *conn;
8982     IConnectionPoint *point;
8983     IXMLDOMDocument *doc;
8984     HRESULT hr;
8985     VARIANT v;
8986     IDispatch *event;
8987
8988     doc = create_document(&IID_IXMLDOMDocument);
8989     if (!doc) return;
8990
8991     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8992     ok(hr == S_OK, "got 0x%08x\n", hr);
8993
8994     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8995     ok(hr == S_OK, "got 0x%08x\n", hr);
8996     IConnectionPoint_Release(point);
8997     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8998     ok(hr == S_OK, "got 0x%08x\n", hr);
8999     IConnectionPoint_Release(point);
9000     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
9001     ok(hr == S_OK, "got 0x%08x\n", hr);
9002     IConnectionPoint_Release(point);
9003
9004     IConnectionPointContainer_Release(conn);
9005
9006     /* ready state callback */
9007     VariantInit(&v);
9008     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9009     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9010
9011     event = create_dispevent();
9012     V_VT(&v) = VT_UNKNOWN;
9013     V_UNKNOWN(&v) = (IUnknown*)event;
9014
9015     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9016     ok(hr == S_OK, "got 0x%08x\n", hr);
9017     EXPECT_REF(event, 2);
9018
9019     V_VT(&v) = VT_DISPATCH;
9020     V_DISPATCH(&v) = event;
9021
9022     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9023     ok(hr == S_OK, "got 0x%08x\n", hr);
9024     EXPECT_REF(event, 2);
9025
9026     /* VT_NULL doesn't reset event handler */
9027     V_VT(&v) = VT_NULL;
9028     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9029     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9030     EXPECT_REF(event, 2);
9031
9032     V_VT(&v) = VT_DISPATCH;
9033     V_DISPATCH(&v) = NULL;
9034
9035     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9036     ok(hr == S_OK, "got 0x%08x\n", hr);
9037     EXPECT_REF(event, 1);
9038
9039     V_VT(&v) = VT_UNKNOWN;
9040     V_DISPATCH(&v) = NULL;
9041     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9042     ok(hr == S_OK, "got 0x%08x\n", hr);
9043
9044     IDispatch_Release(event);
9045
9046     IXMLDOMDocument_Release(doc);
9047 }
9048
9049 static void test_createProcessingInstruction(void)
9050 {
9051     static const WCHAR bodyW[] = {'t','e','s','t',0};
9052     IXMLDOMProcessingInstruction *pi;
9053     IXMLDOMDocument *doc;
9054     WCHAR buff[10];
9055     HRESULT hr;
9056
9057     doc = create_document(&IID_IXMLDOMDocument);
9058     if (!doc) return;
9059
9060     /* test for BSTR handling, pass broken BSTR */
9061     memcpy(&buff[2], bodyW, sizeof(bodyW));
9062     /* just a big length */
9063     *(DWORD*)buff = 0xf0f0;
9064     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9065     ok(hr == S_OK, "got 0x%08x\n", hr);
9066
9067     IXMLDOMProcessingInstruction_Release(pi);
9068     IXMLDOMDocument_Release(doc);
9069 }
9070
9071 static void test_put_nodeTypedValue(void)
9072 {
9073     IXMLDOMDocument *doc;
9074     IXMLDOMElement *elem;
9075     VARIANT type;
9076     HRESULT hr;
9077
9078     doc = create_document(&IID_IXMLDOMDocument);
9079     if (!doc) return;
9080
9081     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9082     ok(hr == S_OK, "got 0x%08x\n", hr);
9083
9084     V_VT(&type) = VT_EMPTY;
9085     hr = IXMLDOMElement_get_dataType(elem, &type);
9086     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9087     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9088
9089     /* set typed value for untyped node */
9090     V_VT(&type) = VT_I1;
9091     V_I1(&type) = 1;
9092     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9093     ok(hr == S_OK, "got 0x%08x\n", hr);
9094
9095     V_VT(&type) = VT_EMPTY;
9096     hr = IXMLDOMElement_get_dataType(elem, &type);
9097     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9098     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9099
9100     /* no type info stored */
9101     V_VT(&type) = VT_EMPTY;
9102     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9103     ok(hr == S_OK, "got 0x%08x\n", hr);
9104     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9105     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9106        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9107     VariantClear(&type);
9108
9109     IXMLDOMElement_Release(elem);
9110     IXMLDOMDocument_Release(doc);
9111     free_bstrs();
9112 }
9113
9114 static void test_get_xml(void)
9115 {
9116     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9117     static const char fooA[] = "<foo/>";
9118     IXMLDOMProcessingInstruction *pi;
9119     IXMLDOMNode *first;
9120     IXMLDOMElement *elem = NULL;
9121     IXMLDOMDocument *doc;
9122     VARIANT_BOOL b;
9123     VARIANT v;
9124     BSTR xml;
9125     HRESULT hr;
9126
9127     doc = create_document(&IID_IXMLDOMDocument);
9128     if (!doc) return;
9129
9130     b = VARIANT_TRUE;
9131     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9132     ok(hr == S_OK, "got 0x%08x\n", hr);
9133     ok( b == VARIANT_TRUE, "got %d\n", b);
9134
9135     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9136                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9137     ok(hr == S_OK, "got 0x%08x\n", hr);
9138
9139     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9140     ok(hr == S_OK, "got 0x%08x\n", hr);
9141
9142     V_UNKNOWN(&v) = (IUnknown*)first;
9143     V_VT(&v) = VT_UNKNOWN;
9144
9145     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9146     ok(hr == S_OK, "got 0x%08x\n", hr);
9147
9148     IXMLDOMProcessingInstruction_Release(pi);
9149     IXMLDOMNode_Release(first);
9150
9151     hr = IXMLDOMDocument_get_xml(doc, &xml);
9152     ok(hr == S_OK, "got 0x%08x\n", hr);
9153
9154     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9155         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9156     SysFreeString(xml);
9157
9158     IXMLDOMDocument_Release(doc);
9159
9160     doc = create_document(&IID_IXMLDOMDocument);
9161
9162     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9163     ok(hr == S_OK, "got 0x%08x\n", hr);
9164
9165     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9166     ok(hr == S_OK, "got 0x%08x\n", hr);
9167
9168     hr = IXMLDOMDocument_get_xml(doc, &xml);
9169     ok(hr == S_OK, "got 0x%08x\n", hr);
9170
9171     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9172         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9173     SysFreeString(xml);
9174
9175     IXMLDOMElement_Release(elem);
9176     IXMLDOMDocument_Release(doc);
9177
9178     free_bstrs();
9179 }
9180
9181 static void test_xsltemplate(void)
9182 {
9183     IXSLTemplate *template;
9184     IXSLProcessor *processor;
9185     IXMLDOMDocument *doc, *doc2;
9186     IStream *stream;
9187     VARIANT_BOOL b;
9188     HRESULT hr;
9189     ULONG ref1, ref2;
9190     VARIANT v;
9191
9192     template = create_xsltemplate(&IID_IXSLTemplate);
9193     if (!template) return;
9194
9195     /* works as reset */
9196     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9197     ok(hr == S_OK, "got 0x%08x\n", hr);
9198
9199     doc = create_document(&IID_IXMLDOMDocument);
9200
9201     b = VARIANT_TRUE;
9202     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9203     ok(hr == S_OK, "got 0x%08x\n", hr);
9204     ok( b == VARIANT_TRUE, "got %d\n", b);
9205
9206     /* putref with non-xsl document */
9207     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9208     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9209
9210     b = VARIANT_TRUE;
9211     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9212     ok(hr == S_OK, "got 0x%08x\n", hr);
9213     ok( b == VARIANT_TRUE, "got %d\n", b);
9214
9215     /* not a freethreaded document */
9216     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9217     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9218
9219     IXMLDOMDocument_Release(doc);
9220
9221     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9222     if (hr != S_OK)
9223     {
9224         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9225         IXSLTemplate_Release(template);
9226         return;
9227     }
9228
9229     b = VARIANT_TRUE;
9230     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9231     ok(hr == S_OK, "got 0x%08x\n", hr);
9232     ok( b == VARIANT_TRUE, "got %d\n", b);
9233
9234     /* freethreaded document */
9235     ref1 = IXMLDOMDocument_AddRef(doc);
9236     IXMLDOMDocument_Release(doc);
9237     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9238     ok(hr == S_OK, "got 0x%08x\n", hr);
9239     ref2 = IXMLDOMDocument_AddRef(doc);
9240     IXMLDOMDocument_Release(doc);
9241     ok(ref2 > ref1, "got %d\n", ref2);
9242
9243     /* processor */
9244     hr = IXSLTemplate_createProcessor(template, NULL);
9245     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9246
9247     EXPECT_REF(template, 1);
9248     hr = IXSLTemplate_createProcessor(template, &processor);
9249     ok(hr == S_OK, "got 0x%08x\n", hr);
9250     EXPECT_REF(template, 2);
9251
9252     /* input no set yet */
9253     V_VT(&v) = VT_BSTR;
9254     V_BSTR(&v) = NULL;
9255     hr = IXSLProcessor_get_input(processor, &v);
9256 todo_wine {
9257     ok(hr == S_OK, "got 0x%08x\n", hr);
9258     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9259 }
9260
9261     hr = IXSLProcessor_get_output(processor, NULL);
9262     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9263
9264     /* reset before it was set */
9265     V_VT(&v) = VT_EMPTY;
9266     hr = IXSLProcessor_put_output(processor, v);
9267     ok(hr == S_OK, "got 0x%08x\n", hr);
9268
9269     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9270     EXPECT_REF(stream, 1);
9271
9272     V_VT(&v) = VT_UNKNOWN;
9273     V_UNKNOWN(&v) = (IUnknown*)stream;
9274     hr = IXSLProcessor_put_output(processor, v);
9275     ok(hr == S_OK, "got 0x%08x\n", hr);
9276
9277     /* it seems processor grabs 2 references */
9278     todo_wine EXPECT_REF(stream, 3);
9279
9280     V_VT(&v) = VT_EMPTY;
9281     hr = IXSLProcessor_get_output(processor, &v);
9282     ok(hr == S_OK, "got 0x%08x\n", hr);
9283     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9284     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9285
9286     todo_wine EXPECT_REF(stream, 4);
9287     VariantClear(&v);
9288
9289     hr = IXSLProcessor_transform(processor, NULL);
9290     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9291
9292     /* reset and check stream refcount */
9293     V_VT(&v) = VT_EMPTY;
9294     hr = IXSLProcessor_put_output(processor, v);
9295     ok(hr == S_OK, "got 0x%08x\n", hr);
9296
9297     EXPECT_REF(stream, 1);
9298
9299     IStream_Release(stream);
9300
9301     /* no output interface set, check output */
9302     doc2 = create_document(&IID_IXMLDOMDocument);
9303
9304     b = VARIANT_TRUE;
9305     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9306     ok(hr == S_OK, "got 0x%08x\n", hr);
9307     ok( b == VARIANT_TRUE, "got %d\n", b);
9308
9309     V_VT(&v) = VT_UNKNOWN;
9310     V_UNKNOWN(&v) = (IUnknown*)doc2;
9311     hr = IXSLProcessor_put_input(processor, v);
9312     ok(hr == S_OK, "got 0x%08x\n", hr);
9313
9314     hr = IXSLProcessor_transform(processor, &b);
9315     ok(hr == S_OK, "got 0x%08x\n", hr);
9316
9317     V_VT(&v) = VT_EMPTY;
9318     hr = IXSLProcessor_get_output(processor, &v);
9319     ok(hr == S_OK, "got 0x%08x\n", hr);
9320     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9321     /* we currently output one '\n' instead of empty string */
9322     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9323     IXMLDOMDocument_Release(doc2);
9324     VariantClear(&v);
9325
9326     IXSLProcessor_Release(processor);
9327
9328     /* drop reference */
9329     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9330     ok(hr == S_OK, "got 0x%08x\n", hr);
9331     ref2 = IXMLDOMDocument_AddRef(doc);
9332     IXMLDOMDocument_Release(doc);
9333     ok(ref2 == ref1, "got %d\n", ref2);
9334
9335     IXMLDOMDocument_Release(doc);
9336     IXSLTemplate_Release(template);
9337     free_bstrs();
9338 }
9339
9340 static void test_insertBefore(void)
9341 {
9342     IXMLDOMDocument *doc, *doc2;
9343     IXMLDOMAttribute *attr;
9344     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9345     IXMLDOMNode *node, *newnode;
9346     HRESULT hr;
9347     VARIANT v;
9348     BSTR p;
9349
9350     doc = create_document(&IID_IXMLDOMDocument);
9351
9352     /* insertBefore behaviour for attribute node */
9353     V_VT(&v) = VT_I4;
9354     V_I4(&v) = NODE_ATTRIBUTE;
9355
9356     attr = NULL;
9357     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9358     ok(hr == S_OK, "got 0x%08x\n", hr);
9359     ok(attr != NULL, "got %p\n", attr);
9360
9361     /* attribute to attribute */
9362     V_VT(&v) = VT_I4;
9363     V_I4(&v) = NODE_ATTRIBUTE;
9364     newnode = NULL;
9365     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9366     ok(hr == S_OK, "got 0x%08x\n", hr);
9367     ok(newnode != NULL, "got %p\n", newnode);
9368
9369     V_VT(&v) = VT_NULL;
9370     node = (void*)0xdeadbeef;
9371     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9372     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9373     ok(node == NULL, "got %p\n", node);
9374
9375     V_VT(&v) = VT_UNKNOWN;
9376     V_UNKNOWN(&v) = (IUnknown*)attr;
9377     node = (void*)0xdeadbeef;
9378     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9379     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9380     ok(node == NULL, "got %p\n", node);
9381     IXMLDOMNode_Release(newnode);
9382
9383     /* cdata to attribute */
9384     V_VT(&v) = VT_I4;
9385     V_I4(&v) = NODE_CDATA_SECTION;
9386     newnode = NULL;
9387     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9388     ok(hr == S_OK, "got 0x%08x\n", hr);
9389     ok(newnode != NULL, "got %p\n", newnode);
9390
9391     V_VT(&v) = VT_NULL;
9392     node = (void*)0xdeadbeef;
9393     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9394     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9395     ok(node == NULL, "got %p\n", node);
9396     IXMLDOMNode_Release(newnode);
9397
9398     /* comment to attribute */
9399     V_VT(&v) = VT_I4;
9400     V_I4(&v) = NODE_COMMENT;
9401     newnode = NULL;
9402     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9403     ok(hr == S_OK, "got 0x%08x\n", hr);
9404     ok(newnode != NULL, "got %p\n", newnode);
9405
9406     V_VT(&v) = VT_NULL;
9407     node = (void*)0xdeadbeef;
9408     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9409     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9410     ok(node == NULL, "got %p\n", node);
9411     IXMLDOMNode_Release(newnode);
9412
9413     /* element to attribute */
9414     V_VT(&v) = VT_I4;
9415     V_I4(&v) = NODE_ELEMENT;
9416     newnode = NULL;
9417     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9418     ok(hr == S_OK, "got 0x%08x\n", hr);
9419     ok(newnode != NULL, "got %p\n", newnode);
9420
9421     V_VT(&v) = VT_NULL;
9422     node = (void*)0xdeadbeef;
9423     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9424     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9425     ok(node == NULL, "got %p\n", node);
9426     IXMLDOMNode_Release(newnode);
9427
9428     /* pi to attribute */
9429     V_VT(&v) = VT_I4;
9430     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9431     newnode = NULL;
9432     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9433     ok(hr == S_OK, "got 0x%08x\n", hr);
9434     ok(newnode != NULL, "got %p\n", newnode);
9435
9436     V_VT(&v) = VT_NULL;
9437     node = (void*)0xdeadbeef;
9438     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9439     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9440     ok(node == NULL, "got %p\n", node);
9441     IXMLDOMNode_Release(newnode);
9442     IXMLDOMAttribute_Release(attr);
9443
9444     /* insertBefore for elements */
9445     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9446     ok(hr == S_OK, "got 0x%08x\n", hr);
9447
9448     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9449     ok(hr == S_OK, "got 0x%08x\n", hr);
9450
9451     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9452     ok(hr == S_OK, "got 0x%08x\n", hr);
9453
9454     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9455     ok(hr == S_OK, "got 0x%08x\n", hr);
9456
9457     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9458     ok(hr == S_OK, "got 0x%08x\n", hr);
9459
9460     EXPECT_NO_CHILDREN(elem1);
9461     EXPECT_NO_CHILDREN(elem2);
9462     EXPECT_NO_CHILDREN(elem3);
9463
9464     todo_wine EXPECT_REF(elem2, 2);
9465
9466     V_VT(&v) = VT_DISPATCH;
9467     V_DISPATCH(&v) = NULL;
9468     node = NULL;
9469     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9470     ok(hr == S_OK, "got 0x%08x\n", hr);
9471     ok(node == (void*)elem4, "got %p\n", node);
9472
9473     EXPECT_CHILDREN(elem1);
9474     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9475     EXPECT_HR(hr, S_OK);
9476     IXMLDOMElement_Release(elem4);
9477
9478     EXPECT_NO_CHILDREN(elem1);
9479
9480     V_VT(&v) = VT_NULL;
9481     node = NULL;
9482     hr = IXMLDOMElement_insertBefore(elem1, (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(elem1);
9487     todo_wine EXPECT_REF(elem2, 3);
9488     IXMLDOMNode_Release(node);
9489
9490     /* again for already linked node */
9491     V_VT(&v) = VT_NULL;
9492     node = NULL;
9493     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9494     ok(hr == S_OK, "got 0x%08x\n", hr);
9495     ok(node == (void*)elem2, "got %p\n", node);
9496
9497     EXPECT_CHILDREN(elem1);
9498
9499     /* increments each time */
9500     todo_wine EXPECT_REF(elem2, 3);
9501     IXMLDOMNode_Release(node);
9502
9503     /* try to add to another element */
9504     V_VT(&v) = VT_NULL;
9505     node = (void*)0xdeadbeef;
9506     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9507     ok(hr == S_OK, "got 0x%08x\n", hr);
9508     ok(node == (void*)elem2, "got %p\n", node);
9509
9510     EXPECT_CHILDREN(elem3);
9511     EXPECT_NO_CHILDREN(elem1);
9512
9513     IXMLDOMNode_Release(node);
9514
9515     /* cross document case - try to add as child to a node created with other doc */
9516     doc2 = create_document(&IID_IXMLDOMDocument);
9517
9518     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9519     ok(hr == S_OK, "got 0x%08x\n", hr);
9520     todo_wine EXPECT_REF(elem4, 2);
9521
9522     /* same name, another instance */
9523     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9524     ok(hr == S_OK, "got 0x%08x\n", hr);
9525     todo_wine EXPECT_REF(elem5, 2);
9526
9527     todo_wine EXPECT_REF(elem3, 2);
9528     V_VT(&v) = VT_NULL;
9529     node = NULL;
9530     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9531     ok(hr == S_OK, "got 0x%08x\n", hr);
9532     ok(node == (void*)elem4, "got %p\n", node);
9533     todo_wine EXPECT_REF(elem4, 3);
9534     todo_wine EXPECT_REF(elem3, 2);
9535     IXMLDOMNode_Release(node);
9536
9537     V_VT(&v) = VT_NULL;
9538     node = NULL;
9539     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9540     ok(hr == S_OK, "got 0x%08x\n", hr);
9541     ok(node == (void*)elem5, "got %p\n", node);
9542     todo_wine EXPECT_REF(elem4, 2);
9543     todo_wine EXPECT_REF(elem5, 3);
9544     IXMLDOMNode_Release(node);
9545
9546     IXMLDOMDocument_Release(doc2);
9547
9548     IXMLDOMElement_Release(elem1);
9549     IXMLDOMElement_Release(elem2);
9550     IXMLDOMElement_Release(elem3);
9551     IXMLDOMElement_Release(elem4);
9552     IXMLDOMElement_Release(elem5);
9553
9554     /* elements with same default namespace */
9555     V_VT(&v) = VT_I4;
9556     V_I4(&v) = NODE_ELEMENT;
9557     elem1 = NULL;
9558     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9559     ok(hr == S_OK, "got 0x%08x\n", hr);
9560     ok(elem1 != NULL, "got %p\n", elem1);
9561
9562     V_VT(&v) = VT_I4;
9563     V_I4(&v) = NODE_ELEMENT;
9564     elem2 = NULL;
9565     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9566     ok(hr == S_OK, "got 0x%08x\n", hr);
9567     ok(elem2 != NULL, "got %p\n", elem2);
9568
9569     /* check contents so far */
9570     p = NULL;
9571     hr = IXMLDOMElement_get_xml(elem1, &p);
9572     ok(hr == S_OK, "got 0x%08x\n", hr);
9573     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9574     SysFreeString(p);
9575
9576     p = NULL;
9577     hr = IXMLDOMElement_get_xml(elem2, &p);
9578     ok(hr == S_OK, "got 0x%08x\n", hr);
9579     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9580     SysFreeString(p);
9581
9582     V_VT(&v) = VT_NULL;
9583     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9584     ok(hr == S_OK, "got 0x%08x\n", hr);
9585
9586     /* get_xml depends on context, for top node it omits child namespace attribute,
9587        but at child level it's still returned */
9588     p = NULL;
9589     hr = IXMLDOMElement_get_xml(elem1, &p);
9590     ok(hr == S_OK, "got 0x%08x\n", hr);
9591     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9592         "got %s\n", wine_dbgstr_w(p));
9593     SysFreeString(p);
9594
9595     p = NULL;
9596     hr = IXMLDOMElement_get_xml(elem2, &p);
9597     ok(hr == S_OK, "got 0x%08x\n", hr);
9598     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9599     SysFreeString(p);
9600
9601     IXMLDOMElement_Release(elem1);
9602     IXMLDOMElement_Release(elem2);
9603
9604     /* child without default namespace added to node with default namespace */
9605     V_VT(&v) = VT_I4;
9606     V_I4(&v) = NODE_ELEMENT;
9607     elem1 = NULL;
9608     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9609     ok(hr == S_OK, "got 0x%08x\n", hr);
9610     ok(elem1 != NULL, "got %p\n", elem1);
9611
9612     V_VT(&v) = VT_I4;
9613     V_I4(&v) = NODE_ELEMENT;
9614     elem2 = NULL;
9615     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9616     ok(hr == S_OK, "got 0x%08x\n", hr);
9617     ok(elem2 != NULL, "got %p\n", elem2);
9618
9619     EXPECT_REF(elem2, 1);
9620     V_VT(&v) = VT_NULL;
9621     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9622     ok(hr == S_OK, "got 0x%08x\n", hr);
9623     EXPECT_REF(elem2, 1);
9624
9625     p = NULL;
9626     hr = IXMLDOMElement_get_xml(elem2, &p);
9627     ok(hr == S_OK, "got 0x%08x\n", hr);
9628     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9629     SysFreeString(p);
9630
9631     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9632     ok(hr == S_OK, "got 0x%08x\n", hr);
9633
9634     p = NULL;
9635     hr = IXMLDOMElement_get_xml(elem2, &p);
9636     ok(hr == S_OK, "got 0x%08x\n", hr);
9637     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9638     SysFreeString(p);
9639
9640     IXMLDOMElement_Release(elem1);
9641     IXMLDOMElement_Release(elem2);
9642     IXMLDOMDocument_Release(doc);
9643 }
9644
9645 static void test_appendChild(void)
9646 {
9647     IXMLDOMDocument *doc, *doc2;
9648     IXMLDOMElement *elem, *elem2;
9649     HRESULT hr;
9650
9651     doc = create_document(&IID_IXMLDOMDocument);
9652     doc2 = create_document(&IID_IXMLDOMDocument);
9653
9654     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9655     ok(hr == S_OK, "got 0x%08x\n", hr);
9656
9657     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9658     ok(hr == S_OK, "got 0x%08x\n", hr);
9659
9660     EXPECT_REF(doc, 1);
9661     todo_wine EXPECT_REF(elem, 2);
9662     EXPECT_REF(doc2, 1);
9663     todo_wine EXPECT_REF(elem2, 2);
9664     EXPECT_NO_CHILDREN(doc);
9665     EXPECT_NO_CHILDREN(doc2);
9666
9667     /* append from another document */
9668     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9669     ok(hr == S_OK, "got 0x%08x\n", hr);
9670
9671     EXPECT_REF(doc, 1);
9672     todo_wine EXPECT_REF(elem, 2);
9673     EXPECT_REF(doc2, 1);
9674     todo_wine EXPECT_REF(elem2, 2);
9675     EXPECT_NO_CHILDREN(doc);
9676     EXPECT_CHILDREN(doc2);
9677
9678     IXMLDOMElement_Release(elem);
9679     IXMLDOMElement_Release(elem2);
9680     IXMLDOMDocument_Release(doc);
9681     IXMLDOMDocument_Release(doc2);
9682 }
9683
9684 static void test_get_doctype(void)
9685 {
9686     IXMLDOMDocumentType *doctype;
9687     IXMLDOMDocument *doc;
9688     HRESULT hr;
9689
9690     doc = create_document(&IID_IXMLDOMDocument);
9691
9692     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9693     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9694
9695     doctype = (void*)0xdeadbeef;
9696     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9697     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9698     ok(doctype == NULL, "got %p\n", doctype);
9699
9700     IXMLDOMDocument_Release(doc);
9701 }
9702
9703 static void test_get_tagName(void)
9704 {
9705     IXMLDOMDocument *doc;
9706     IXMLDOMElement *elem, *elem2;
9707     HRESULT hr;
9708     BSTR str;
9709
9710     doc = create_document(&IID_IXMLDOMDocument);
9711
9712     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9713     ok(hr == S_OK, "got 0x%08x\n", hr);
9714
9715     hr = IXMLDOMElement_get_tagName(elem, NULL);
9716     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9717
9718     str = NULL;
9719     hr = IXMLDOMElement_get_tagName(elem, &str);
9720     ok(hr == S_OK, "got 0x%08x\n", hr);
9721     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9722     SysFreeString(str);
9723
9724     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9725     ok(hr == S_OK, "got 0x%08x\n", hr);
9726
9727     str = NULL;
9728     hr = IXMLDOMElement_get_tagName(elem2, &str);
9729     ok(hr == S_OK, "got 0x%08x\n", hr);
9730     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9731     SysFreeString(str);
9732
9733     IXMLDOMDocument_Release(elem);
9734     IXMLDOMDocument_Release(elem2);
9735     IXMLDOMDocument_Release(doc);
9736     free_bstrs();
9737 }
9738
9739 typedef struct {
9740     DOMNodeType type;
9741     const char *name;
9742     VARTYPE vt;
9743     HRESULT hr;
9744 } node_type_t;
9745
9746 static const node_type_t get_datatype[] = {
9747     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9748     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9749     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9750     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9751     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9752     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9753     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9754     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9755     { 0 }
9756 };
9757
9758 static void test_get_dataType(void)
9759 {
9760     const node_type_t *entry = get_datatype;
9761     IXMLDOMDocument *doc;
9762
9763     doc = create_document(&IID_IXMLDOMDocument);
9764
9765     while (entry->type)
9766     {
9767         IXMLDOMNode *node = NULL;
9768         VARIANT var, type;
9769         HRESULT hr;
9770
9771         V_VT(&var) = VT_I4;
9772         V_I4(&var) = entry->type;
9773         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9774         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9775
9776         hr = IXMLDOMNode_get_dataType(node, NULL);
9777         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9778
9779         VariantInit(&type);
9780         hr = IXMLDOMNode_get_dataType(node, &type);
9781         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9782             hr, entry->hr, entry->type);
9783         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9784             V_VT(&type), entry->vt, entry->type);
9785         VariantClear(&type);
9786
9787         IXMLDOMNode_Release(node);
9788
9789         entry++;
9790     }
9791
9792     IXMLDOMDocument_Release(doc);
9793     free_bstrs();
9794 }
9795
9796 typedef struct _get_node_typestring_t {
9797     DOMNodeType type;
9798     const char *string;
9799 } get_node_typestring_t;
9800
9801 static const get_node_typestring_t get_node_typestring[] = {
9802     { NODE_ELEMENT,                "element"               },
9803     { NODE_ATTRIBUTE,              "attribute"             },
9804     { NODE_TEXT,                   "text"                  },
9805     { NODE_CDATA_SECTION ,         "cdatasection"          },
9806     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9807     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9808     { NODE_COMMENT,                "comment"               },
9809     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9810     { 0 }
9811 };
9812
9813 static void test_get_nodeTypeString(void)
9814 {
9815     const get_node_typestring_t *entry = get_node_typestring;
9816     IXMLDOMDocument *doc;
9817     HRESULT hr;
9818     BSTR str;
9819
9820     doc = create_document(&IID_IXMLDOMDocument);
9821
9822     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9823     ok(hr == S_OK, "got 0x%08x\n", hr);
9824     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9825     SysFreeString(str);
9826
9827     while (entry->type)
9828     {
9829         IXMLDOMNode *node = NULL;
9830         VARIANT var;
9831
9832         V_VT(&var) = VT_I4;
9833         V_I4(&var) = entry->type;
9834         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9835         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9836
9837         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9838         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9839
9840         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9841         ok(hr == S_OK, "got 0x%08x\n", hr);
9842         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9843             wine_dbgstr_w(str), entry->string, entry->type);
9844         SysFreeString(str);
9845         IXMLDOMNode_Release(node);
9846
9847         entry++;
9848     }
9849
9850     IXMLDOMDocument_Release(doc);
9851     free_bstrs();
9852 }
9853
9854 typedef struct _get_attributes_t {
9855     DOMNodeType type;
9856     HRESULT hr;
9857 } get_attributes_t;
9858
9859 static const get_attributes_t get_attributes[] = {
9860     { NODE_ATTRIBUTE,              S_FALSE },
9861     { NODE_TEXT,                   S_FALSE },
9862     { NODE_CDATA_SECTION ,         S_FALSE },
9863     { NODE_ENTITY_REFERENCE,       S_FALSE },
9864     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9865     { NODE_COMMENT,                S_FALSE },
9866     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9867     { 0 }
9868 };
9869
9870 static void test_get_attributes(void)
9871 {
9872     const get_attributes_t *entry = get_attributes;
9873     IXMLDOMNamedNodeMap *map;
9874     IXMLDOMDocument *doc;
9875     IXMLDOMNode *node, *node2;
9876     VARIANT_BOOL b;
9877     HRESULT hr;
9878     BSTR str;
9879     LONG length;
9880
9881     doc = create_document(&IID_IXMLDOMDocument);
9882
9883     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9884     ok(hr == S_OK, "got %08x\n", hr);
9885
9886     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9887     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9888
9889     map = (void*)0xdeadbeef;
9890     hr = IXMLDOMDocument_get_attributes(doc, &map);
9891     ok(hr == S_FALSE, "got %08x\n", hr);
9892     ok(map == NULL, "got %p\n", map);
9893
9894     /* first child is <?xml ?> */
9895     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9896     ok(hr == S_OK, "got %08x\n", hr);
9897
9898     hr = IXMLDOMNode_get_attributes(node, &map);
9899     ok(hr == S_OK, "got %08x\n", hr);
9900
9901     length = -1;
9902     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9903     EXPECT_HR(hr, S_OK);
9904     todo_wine ok(length == 1, "got %d\n", length);
9905
9906     if (hr == S_OK && length == 1)
9907     {
9908         IXMLDOMAttribute *attr;
9909         DOMNodeType type;
9910         VARIANT v;
9911
9912         node2 = NULL;
9913         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9914         EXPECT_HR(hr, S_OK);
9915         ok(node != NULL, "got %p\n", node2);
9916
9917         hr = IXMLDOMNode_get_nodeName(node2, &str);
9918         EXPECT_HR(hr, S_OK);
9919         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9920         SysFreeString(str);
9921
9922         length = -1;
9923         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9924         EXPECT_HR(hr, S_OK);
9925         ok(length == 1, "got %d\n", length);
9926
9927         type = -1;
9928         hr = IXMLDOMNode_get_nodeType(node2, &type);
9929         EXPECT_HR(hr, S_OK);
9930         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9931
9932         hr = IXMLDOMNode_get_xml(node, &str);
9933         EXPECT_HR(hr, S_OK);
9934         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9935         SysFreeString(str);
9936
9937         hr = IXMLDOMNode_get_text(node, &str);
9938         EXPECT_HR(hr, S_OK);
9939         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9940         SysFreeString(str);
9941
9942         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9943         EXPECT_HR(hr, S_OK);
9944
9945         length = -1;
9946         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9947         EXPECT_HR(hr, S_OK);
9948         ok(length == 0, "got %d\n", length);
9949
9950         hr = IXMLDOMNode_get_xml(node, &str);
9951         EXPECT_HR(hr, S_OK);
9952         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9953         SysFreeString(str);
9954
9955         hr = IXMLDOMNode_get_text(node, &str);
9956         EXPECT_HR(hr, S_OK);
9957         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9958         SysFreeString(str);
9959
9960         IXMLDOMNamedNodeMap_Release(map);
9961
9962         hr = IXMLDOMNode_get_attributes(node, &map);
9963         ok(hr == S_OK, "got %08x\n", hr);
9964
9965         length = -1;
9966         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9967         EXPECT_HR(hr, S_OK);
9968         ok(length == 0, "got %d\n", length);
9969
9970         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9971         EXPECT_HR(hr, S_OK);
9972
9973         V_VT(&v) = VT_BSTR;
9974         V_BSTR(&v) = _bstr_("UTF-8");
9975         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9976         EXPECT_HR(hr, S_OK);
9977
9978         EXPECT_REF(attr, 2);
9979         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9980         EXPECT_HR(hr, S_OK);
9981         EXPECT_REF(attr, 2);
9982
9983         hr = IXMLDOMNode_get_attributes(node, &map);
9984         ok(hr == S_OK, "got %08x\n", hr);
9985
9986         length = -1;
9987         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9988         EXPECT_HR(hr, S_OK);
9989         ok(length == 1, "got %d\n", length);
9990
9991         hr = IXMLDOMNode_get_xml(node, &str);
9992         EXPECT_HR(hr, S_OK);
9993         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9994         SysFreeString(str);
9995
9996         hr = IXMLDOMNode_get_text(node, &str);
9997         EXPECT_HR(hr, S_OK);
9998         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9999         SysFreeString(str);
10000
10001         IXMLDOMNamedNodeMap_Release(map);
10002         IXMLDOMNode_Release(node2);
10003     }
10004
10005     IXMLDOMNode_Release(node);
10006
10007     /* last child is element */
10008     EXPECT_REF(doc, 1);
10009     hr = IXMLDOMDocument_get_lastChild(doc, &node);
10010     ok(hr == S_OK, "got %08x\n", hr);
10011     EXPECT_REF(doc, 1);
10012
10013     EXPECT_REF(node, 1);
10014     hr = IXMLDOMNode_get_attributes(node, &map);
10015     ok(hr == S_OK, "got %08x\n", hr);
10016     EXPECT_REF(node, 1);
10017     EXPECT_REF(doc, 1);
10018
10019     EXPECT_REF(map, 1);
10020     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10021     ok(hr == S_OK, "got %08x\n", hr);
10022     EXPECT_REF(node, 1);
10023     EXPECT_REF(node2, 1);
10024     EXPECT_REF(map, 1);
10025     EXPECT_REF(doc, 1);
10026     IXMLDOMNode_Release(node2);
10027
10028     /* release node before map release, map still works */
10029     IXMLDOMNode_Release(node);
10030
10031     length = 0;
10032     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10033     ok(hr == S_OK, "got %08x\n", hr);
10034     ok(length == 1, "got %d\n", length);
10035
10036     node2 = NULL;
10037     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10038     ok(hr == S_OK, "got %08x\n", hr);
10039     EXPECT_REF(node2, 1);
10040     IXMLDOMNode_Release(node2);
10041
10042     IXMLDOMNamedNodeMap_Release(map);
10043
10044     while (entry->type)
10045     {
10046         VARIANT var;
10047
10048         node = NULL;
10049
10050         V_VT(&var) = VT_I4;
10051         V_I4(&var) = entry->type;
10052         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10053         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10054
10055         hr = IXMLDOMNode_get_attributes(node, NULL);
10056         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10057
10058         map = (void*)0xdeadbeef;
10059         hr = IXMLDOMNode_get_attributes(node, &map);
10060         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10061             hr, entry->hr, entry->type);
10062         ok(map == NULL, "got %p\n", map);
10063
10064         IXMLDOMNode_Release(node);
10065
10066         entry++;
10067     }
10068
10069     IXMLDOMDocument_Release(doc);
10070     free_bstrs();
10071 }
10072
10073 static void test_selection(void)
10074 {
10075     IXMLDOMSelection *selection, *selection2;
10076     IEnumVARIANT *enum1, *enum2, *enum3;
10077     IXMLDOMNodeList *list;
10078     IXMLDOMDocument *doc;
10079     IDispatchEx *dispex;
10080     IXMLDOMNode *node;
10081     IDispatch *disp;
10082     VARIANT_BOOL b;
10083     HRESULT hr;
10084     DISPID did;
10085     VARIANT v;
10086     BSTR name;
10087     ULONG ret;
10088     LONG len;
10089
10090     doc = create_document(&IID_IXMLDOMDocument);
10091
10092     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
10093     EXPECT_HR(hr, S_OK);
10094
10095     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10096     EXPECT_HR(hr, S_OK);
10097
10098     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10099     EXPECT_HR(hr, S_OK);
10100     IXMLDOMSelection_Release(selection);
10101
10102     /* collection disp id */
10103     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10104     EXPECT_HR(hr, S_OK);
10105     did = 0;
10106     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10107     EXPECT_HR(hr, S_OK);
10108     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10109     len = 0;
10110     hr = IXMLDOMSelection_get_length(selection, &len);
10111     EXPECT_HR(hr, S_OK);
10112     ok(len == 1, "got %d\n", len);
10113     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10114     EXPECT_HR(hr, S_OK);
10115     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10116     IDispatchEx_Release(dispex);
10117
10118     /* IEnumVARIANT tests */
10119     enum1 = NULL;
10120     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10121     EXPECT_HR(hr, S_OK);
10122     ok(enum1 != NULL, "got %p\n", enum1);
10123     EXPECT_REF(enum1, 2);
10124
10125     enum3 = NULL;
10126     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10127     EXPECT_HR(hr, S_OK);
10128     ok(enum3 != NULL, "got %p\n", enum3);
10129     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10130     EXPECT_REF(enum1, 3);
10131     IEnumVARIANT_Release(enum3);
10132
10133     EXPECT_REF(selection, 1);
10134     EXPECT_REF(enum1, 2);
10135
10136     enum2 = NULL;
10137     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10138     EXPECT_HR(hr, S_OK);
10139     ok(enum2 != NULL, "got %p\n", enum2);
10140
10141     EXPECT_REF(selection, 2);
10142     EXPECT_REF(enum1, 2);
10143     EXPECT_REF(enum2, 1);
10144
10145     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10146
10147     selection2 = NULL;
10148     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10149     EXPECT_HR(hr, S_OK);
10150     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10151     EXPECT_REF(selection, 3);
10152     EXPECT_REF(enum1, 2);
10153
10154     IXMLDOMSelection_Release(selection2);
10155
10156     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10157     EXPECT_HR(hr, S_OK);
10158     EXPECT_REF(selection, 3);
10159     IDispatch_Release(disp);
10160
10161     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10162     EXPECT_HR(hr, S_OK);
10163     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10164     EXPECT_REF(selection, 2);
10165     EXPECT_REF(enum1, 3);
10166
10167     IEnumVARIANT_Release(enum1);
10168     IEnumVARIANT_Release(enum2);
10169
10170     enum1 = NULL;
10171     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10172     EXPECT_HR(hr, S_OK);
10173     ok(enum1 != NULL, "got %p\n", enum1);
10174     EXPECT_REF(enum1, 1);
10175     EXPECT_REF(selection, 2);
10176
10177     enum2 = NULL;
10178     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10179     EXPECT_HR(hr, S_OK);
10180     ok(enum2 != NULL, "got %p\n", enum2);
10181     EXPECT_REF(enum2, 1);
10182     EXPECT_REF(selection, 3);
10183
10184     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10185
10186     IEnumVARIANT_AddRef(enum1);
10187     EXPECT_REF(selection, 3);
10188     EXPECT_REF(enum1, 2);
10189     EXPECT_REF(enum2, 1);
10190     IEnumVARIANT_Release(enum1);
10191
10192     IEnumVARIANT_Release(enum1);
10193     IEnumVARIANT_Release(enum2);
10194
10195     EXPECT_REF(selection, 1);
10196
10197     IXMLDOMNodeList_Release(list);
10198
10199     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10200     EXPECT_HR(hr, S_OK);
10201
10202     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10203     EXPECT_HR(hr, E_NOINTERFACE);
10204
10205     IXMLDOMNodeList_Release(list);
10206
10207     /* test if IEnumVARIANT touches selection context */
10208     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10209     EXPECT_HR(hr, S_OK);
10210
10211     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10212     EXPECT_HR(hr, S_OK);
10213
10214     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10215     EXPECT_HR(hr, S_OK);
10216
10217     len = 0;
10218     hr = IXMLDOMSelection_get_length(selection, &len);
10219     EXPECT_HR(hr, S_OK);
10220     ok(len == 4, "got %d\n", len);
10221
10222     enum1 = NULL;
10223     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10224     EXPECT_HR(hr, S_OK);
10225
10226     /* no-op if zero count */
10227     V_VT(&v) = VT_I2;
10228     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10229     EXPECT_HR(hr, S_OK);
10230     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10231
10232     /* positive count, null array pointer */
10233     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10234     EXPECT_HR(hr, E_INVALIDARG);
10235
10236     ret = 1;
10237     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10238     EXPECT_HR(hr, E_INVALIDARG);
10239     ok(ret == 0, "got %d\n", ret);
10240
10241     V_VT(&v) = VT_I2;
10242     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10243     EXPECT_HR(hr, S_OK);
10244     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10245
10246     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10247     EXPECT_HR(hr, S_OK);
10248     hr = IXMLDOMNode_get_nodeName(node, &name);
10249     EXPECT_HR(hr, S_OK);
10250     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10251     SysFreeString(name);
10252     IXMLDOMNode_Release(node);
10253     VariantClear(&v);
10254
10255     /* list cursor is updated */
10256     hr = IXMLDOMSelection_nextNode(selection, &node);
10257     EXPECT_HR(hr, S_OK);
10258     hr = IXMLDOMNode_get_nodeName(node, &name);
10259     EXPECT_HR(hr, S_OK);
10260     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10261     IXMLDOMNode_Release(node);
10262
10263     V_VT(&v) = VT_I2;
10264     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10265     EXPECT_HR(hr, S_OK);
10266     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10267     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10268     EXPECT_HR(hr, S_OK);
10269     hr = IXMLDOMNode_get_nodeName(node, &name);
10270     EXPECT_HR(hr, S_OK);
10271     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10272     SysFreeString(name);
10273     IXMLDOMNode_Release(node);
10274     VariantClear(&v);
10275
10276     hr = IXMLDOMSelection_nextNode(selection, &node);
10277     EXPECT_HR(hr, S_OK);
10278     hr = IXMLDOMNode_get_nodeName(node, &name);
10279     EXPECT_HR(hr, S_OK);
10280     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10281     IXMLDOMNode_Release(node);
10282
10283     IXMLDOMSelection_Release(selection);
10284     IXMLDOMNodeList_Release(list);
10285     IXMLDOMDocument_Release(doc);
10286
10287     free_bstrs();
10288 }
10289
10290 static void test_load(void)
10291 {
10292     IXMLDOMDocument *doc;
10293     IXMLDOMNodeList *list;
10294     VARIANT_BOOL b;
10295     HANDLE hfile;
10296     VARIANT src;
10297     HRESULT hr;
10298     BOOL ret;
10299     BSTR path, bstr1, bstr2;
10300     DWORD written;
10301     void* ptr;
10302
10303     /* prepare a file */
10304     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10305     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10306     if(hfile == INVALID_HANDLE_VALUE) return;
10307
10308     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10309     ok(ret, "WriteFile failed\n");
10310
10311     CloseHandle(hfile);
10312
10313     doc = create_document(&IID_IXMLDOMDocument);
10314
10315     path = _bstr_("test.xml");
10316
10317     /* load from path: VT_BSTR */
10318     V_VT(&src) = VT_BSTR;
10319     V_BSTR(&src) = path;
10320     hr = IXMLDOMDocument_load(doc, src, &b);
10321     EXPECT_HR(hr, S_OK);
10322     ok(b == VARIANT_TRUE, "got %d\n", b);
10323
10324     /* load from a path: VT_BSTR|VT_BYREF */
10325     V_VT(&src) = VT_BSTR | VT_BYREF;
10326     V_BSTRREF(&src) = &path;
10327     hr = IXMLDOMDocument_load(doc, src, &b);
10328     EXPECT_HR(hr, S_OK);
10329     ok(b == VARIANT_TRUE, "got %d\n", b);
10330
10331     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10332     V_VT(&src) = VT_BSTR | VT_BYREF;
10333     V_BSTRREF(&src) = NULL;
10334     hr = IXMLDOMDocument_load(doc, src, &b);
10335     EXPECT_HR(hr, E_INVALIDARG);
10336     ok(b == VARIANT_FALSE, "got %d\n", b);
10337
10338     IXMLDOMDocument_Release(doc);
10339
10340     DeleteFileA("test.xml");
10341
10342     doc = create_document(&IID_IXMLDOMDocument);
10343
10344     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10345     EXPECT_HR(hr, S_OK);
10346     ok(b == VARIANT_TRUE, "got %d\n", b);
10347
10348     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10349     EXPECT_HR(hr, S_OK);
10350     bstr1 = _bstr_(list_to_string(list));
10351
10352     hr = IXMLDOMNodeList_reset(list);
10353     EXPECT_HR(hr, S_OK);
10354
10355     IXMLDOMDocument_Release(doc);
10356
10357     doc = create_document(&IID_IXMLDOMDocument);
10358
10359     VariantInit(&src);
10360     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10361     V_VT(&src) = VT_ARRAY|VT_UI1;
10362     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10363     ptr = NULL;
10364     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10365     EXPECT_HR(hr, S_OK);
10366     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10367
10368     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10369     hr = SafeArrayUnlock(V_ARRAY(&src));
10370     EXPECT_HR(hr, S_OK);
10371
10372     hr = IXMLDOMDocument_load(doc, src, &b);
10373     EXPECT_HR(hr, S_OK);
10374     ok(b == VARIANT_TRUE, "got %d\n", b);
10375
10376     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10377     EXPECT_HR(hr, S_OK);
10378     bstr2 = _bstr_(list_to_string(list));
10379
10380     hr = IXMLDOMNodeList_reset(list);
10381     EXPECT_HR(hr, S_OK);
10382
10383     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10384        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10385
10386     IXMLDOMDocument_Release(doc);
10387     IXMLDOMNodeList_Release(list);
10388     VariantClear(&src);
10389
10390     /* UTF-16 isn't accepted */
10391     doc = create_document(&IID_IXMLDOMDocument);
10392
10393     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10394     V_VT(&src) = VT_ARRAY|VT_UI1;
10395     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10396     ptr = NULL;
10397     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10398     EXPECT_HR(hr, S_OK);
10399     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10400
10401     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10402     hr = SafeArrayUnlock(V_ARRAY(&src));
10403     EXPECT_HR(hr, S_OK);
10404
10405     hr = IXMLDOMDocument_load(doc, src, &b);
10406     todo_wine EXPECT_HR(hr, S_FALSE);
10407     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10408
10409     VariantClear(&src);
10410
10411     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10412     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10413     V_VT(&src) = VT_ARRAY|VT_UI2;
10414     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10415     ptr = NULL;
10416     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10417     EXPECT_HR(hr, S_OK);
10418     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10419
10420     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10421     hr = SafeArrayUnlock(V_ARRAY(&src));
10422     EXPECT_HR(hr, S_OK);
10423
10424     hr = IXMLDOMDocument_load(doc, src, &b);
10425     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10426     ok(b == VARIANT_FALSE, "got %d\n", b);
10427
10428     VariantClear(&src);
10429     IXMLDOMDocument_Release(doc);
10430
10431     free_bstrs();
10432 }
10433
10434 static void test_domobj_dispex(IUnknown *obj)
10435 {
10436     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10437     IDispatchEx *dispex;
10438     IUnknown *unk;
10439     DWORD props;
10440     UINT ticnt;
10441     HRESULT hr;
10442     BSTR name;
10443
10444     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10445     EXPECT_HR(hr, S_OK);
10446     if (FAILED(hr)) return;
10447
10448     ticnt = 0;
10449     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10450     EXPECT_HR(hr, S_OK);
10451     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10452
10453     name = SysAllocString(szstar);
10454     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10455     EXPECT_HR(hr, E_NOTIMPL);
10456     SysFreeString(name);
10457
10458     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10459     EXPECT_HR(hr, E_NOTIMPL);
10460
10461     props = 0;
10462     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10463     EXPECT_HR(hr, E_NOTIMPL);
10464     ok(props == 0, "expected 0 got %d\n", props);
10465
10466     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10467     EXPECT_HR(hr, E_NOTIMPL);
10468     if (SUCCEEDED(hr)) SysFreeString(name);
10469
10470     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10471     EXPECT_HR(hr, E_NOTIMPL);
10472
10473     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10474     EXPECT_HR(hr, E_NOTIMPL);
10475     if (hr == S_OK && unk) IUnknown_Release(unk);
10476
10477     IDispatchEx_Release(dispex);
10478 }
10479
10480 static void test_mxnamespacemanager(void)
10481 {
10482     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10483     IVBMXNamespaceManager *mgr2;
10484     IMXNamespaceManager *nsmgr;
10485     WCHAR buffW[250];
10486     IDispatch *disp;
10487     IUnknown *unk;
10488     HRESULT hr;
10489     INT len;
10490
10491     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10492         &IID_IMXNamespaceManager, (void**)&nsmgr);
10493     EXPECT_HR(hr, S_OK);
10494
10495     /* IMXNamespaceManager inherits from IUnknown */
10496     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10497     EXPECT_HR(hr, S_OK);
10498     IDispatch_Release(disp);
10499
10500     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10501     EXPECT_HR(hr, S_OK);
10502     IVBMXNamespaceManager_Release(mgr2);
10503
10504     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10505     EXPECT_HR(hr, S_OK);
10506
10507     /* prefix already added */
10508     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10509     EXPECT_HR(hr, S_FALSE);
10510
10511     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10512     EXPECT_HR(hr, E_INVALIDARG);
10513
10514     /* "xml" and "xmlns" are not allowed here */
10515     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10516     EXPECT_HR(hr, E_INVALIDARG);
10517
10518     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10519     EXPECT_HR(hr, E_INVALIDARG);
10520 todo_wine {
10521     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10522     EXPECT_HR(hr, E_FAIL);
10523 }
10524     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10525     EXPECT_HR(hr, E_POINTER);
10526
10527     len = -1;
10528     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10529     EXPECT_HR(hr, S_OK);
10530     ok(len == 3, "got %d\n", len);
10531
10532     len = -1;
10533     buffW[0] = 0x1;
10534     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10535     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10536     ok(len == -1, "got %d\n", len);
10537     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10538
10539     len = 10;
10540     buffW[0] = 0x1;
10541     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10542     EXPECT_HR(hr, S_OK);
10543     ok(len == 3, "got %d\n", len);
10544     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10545
10546     /* getURI */
10547     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10548     EXPECT_HR(hr, E_INVALIDARG);
10549
10550     len = -1;
10551     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10552     EXPECT_HR(hr, E_INVALIDARG);
10553     ok(len == -1, "got %d\n", len);
10554
10555     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10556     EXPECT_HR(hr, E_POINTER);
10557
10558     len = -1;
10559     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10560     EXPECT_HR(hr, S_OK);
10561     /* length of "xml" uri is constant */
10562     ok(len == strlen(xmluriA), "got %d\n", len);
10563
10564     len = 100;
10565     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10566     EXPECT_HR(hr, S_OK);
10567     ok(len == strlen(xmluriA), "got %d\n", len);
10568     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10569
10570     len = strlen(xmluriA)-1;
10571     buffW[0] = 0x1;
10572     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10573     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10574     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10575     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10576
10577     /* prefix xml1 not defined */
10578     len = -1;
10579     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10580     EXPECT_HR(hr, S_FALSE);
10581     ok(len == 0, "got %d\n", len);
10582
10583     len = 100;
10584     buffW[0] = 0x1;
10585     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10586     EXPECT_HR(hr, S_FALSE);
10587     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10588     ok(len == 0, "got %d\n", len);
10589
10590     /* IDispatchEx tests */
10591     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10592     EXPECT_HR(hr, S_OK);
10593     test_domobj_dispex(unk);
10594     IUnknown_Release(unk);
10595
10596     IMXNamespaceManager_Release(nsmgr);
10597
10598     /* ::getPrefix() */
10599     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10600         &IID_IMXNamespaceManager, (void**)&nsmgr);
10601     EXPECT_HR(hr, S_OK);
10602
10603     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10604     EXPECT_HR(hr, E_INVALIDARG);
10605
10606     len = -1;
10607     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10608     EXPECT_HR(hr, E_INVALIDARG);
10609     ok(len == -1, "got %d\n", len);
10610
10611     len = 100;
10612     buffW[0] = 0x1;
10613     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10614     EXPECT_HR(hr, E_FAIL);
10615     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10616     ok(len == 100, "got %d\n", len);
10617
10618     len = 0;
10619     buffW[0] = 0x1;
10620     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10621     EXPECT_HR(hr, E_FAIL);
10622     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10623     ok(len == 0, "got %d\n", len);
10624
10625     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10626     EXPECT_HR(hr, S_OK);
10627
10628     len = 100;
10629     buffW[0] = 0x1;
10630     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10631     EXPECT_HR(hr, S_OK);
10632     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10633     ok(len == 3, "got %d\n", len);
10634
10635     len = 100;
10636     buffW[0] = 0x1;
10637     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10638     EXPECT_HR(hr, S_OK);
10639     ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10640     ok(len == 3, "got %d\n", len);
10641
10642     /* with null buffer it's possible to get required length */
10643     len = 100;
10644     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10645     EXPECT_HR(hr, S_OK);
10646     ok(len == 3, "got %d\n", len);
10647
10648     len = 0;
10649     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10650     EXPECT_HR(hr, S_OK);
10651     ok(len == 3, "got %d\n", len);
10652
10653     len = 100;
10654     buffW[0] = 0x1;
10655     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10656     EXPECT_HR(hr, E_FAIL);
10657     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10658     ok(len == 100, "got %d\n", len);
10659
10660     len = 100;
10661     buffW[0] = 0x1;
10662     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10663     EXPECT_HR(hr, E_FAIL);
10664     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10665     ok(len == 100, "got %d\n", len);
10666
10667     len = 100;
10668     buffW[0] = 0x1;
10669     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10670     EXPECT_HR(hr, E_INVALIDARG);
10671     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10672     ok(len == 100, "got %d\n", len);
10673
10674     len = 100;
10675     buffW[0] = 0x1;
10676     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10677     EXPECT_HR(hr, E_INVALIDARG);
10678     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10679     ok(len == 100, "got %d\n", len);
10680
10681     len = 100;
10682     buffW[0] = 0x1;
10683     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10684     EXPECT_HR(hr, E_INVALIDARG);
10685     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10686     ok(len == 100, "got %d\n", len);
10687
10688     len = 100;
10689     buffW[0] = 0x1;
10690     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10691     EXPECT_HR(hr, E_FAIL);
10692     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10693     ok(len == 100, "got %d\n", len);
10694
10695     len = 100;
10696     buffW[0] = 0x1;
10697     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10698     EXPECT_HR(hr, E_INVALIDARG);
10699     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10700     ok(len == 100, "got %d\n", len);
10701
10702     /* declare another one, indices are shifted */
10703     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10704     EXPECT_HR(hr, S_OK);
10705
10706     len = 100;
10707     buffW[0] = 0x1;
10708     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10709     EXPECT_HR(hr, S_OK);
10710     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10711     ok(len == 3, "got %d\n", len);
10712
10713     len = 100;
10714     buffW[0] = 0x1;
10715     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10716     EXPECT_HR(hr, S_OK);
10717     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10718     ok(len == 3, "got %d\n", len);
10719
10720     len = 100;
10721     buffW[0] = 0x1;
10722     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10723     EXPECT_HR(hr, E_FAIL);
10724     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10725     ok(len == 100, "got %d\n", len);
10726
10727     len = 100;
10728     buffW[0] = 0x1;
10729     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10730     EXPECT_HR(hr, E_INVALIDARG);
10731     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10732     ok(len == 100, "got %d\n", len);
10733
10734     IMXNamespaceManager_Release(nsmgr);
10735
10736     /* push/pop tests */
10737     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10738         &IID_IMXNamespaceManager, (void**)&nsmgr);
10739     EXPECT_HR(hr, S_OK);
10740
10741     /* pop with empty stack */
10742     hr = IMXNamespaceManager_popContext(nsmgr);
10743     EXPECT_HR(hr, E_FAIL);
10744
10745     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10746     EXPECT_HR(hr, S_OK);
10747
10748     len = 100;
10749     buffW[0] = 0x1;
10750     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10751     EXPECT_HR(hr, S_OK);
10752     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10753     ok(len == 3, "got %d\n", len);
10754
10755     hr = IMXNamespaceManager_pushContext(nsmgr);
10756     EXPECT_HR(hr, S_OK);
10757
10758     len = 100;
10759     buffW[0] = 0x1;
10760     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10761     EXPECT_HR(hr, S_OK);
10762     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10763     ok(len == 3, "got %d\n", len);
10764
10765     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10766     EXPECT_HR(hr, S_OK);
10767
10768     len = 100;
10769     buffW[0] = 0x1;
10770     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10771     EXPECT_HR(hr, S_OK);
10772     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10773     ok(len == 3, "got %d\n", len);
10774
10775     hr = IMXNamespaceManager_pushContext(nsmgr);
10776     EXPECT_HR(hr, S_OK);
10777     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
10778     EXPECT_HR(hr, S_OK);
10779
10780     len = 100;
10781     buffW[0] = 0x1;
10782     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10783     EXPECT_HR(hr, S_OK);
10784     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10785     ok(len == 3, "got %d\n", len);
10786
10787     len = 100;
10788     buffW[0] = 0x1;
10789     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10790     EXPECT_HR(hr, S_OK);
10791     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10792     ok(len == 3, "got %d\n", len);
10793
10794     hr = IMXNamespaceManager_popContext(nsmgr);
10795     EXPECT_HR(hr, S_OK);
10796
10797     hr = IMXNamespaceManager_popContext(nsmgr);
10798     EXPECT_HR(hr, S_OK);
10799
10800     len = 100;
10801     buffW[0] = 0x1;
10802     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10803     EXPECT_HR(hr, E_FAIL);
10804     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10805     ok(len == 100, "got %d\n", len);
10806
10807     len = 100;
10808     buffW[0] = 0x1;
10809     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10810     EXPECT_HR(hr, S_OK);
10811     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10812     ok(len == 3, "got %d\n", len);
10813
10814     IMXNamespaceManager_Release(nsmgr);
10815
10816     free_bstrs();
10817 }
10818
10819 static void test_mxnamespacemanager_override(void)
10820 {
10821     IMXNamespaceManager *nsmgr;
10822     WCHAR buffW[250];
10823     VARIANT_BOOL b;
10824     HRESULT hr;
10825     INT len;
10826
10827     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10828         &IID_IMXNamespaceManager, (void**)&nsmgr);
10829     EXPECT_HR(hr, S_OK);
10830
10831     len = sizeof(buffW)/sizeof(WCHAR);
10832     buffW[0] = 0;
10833     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10834     EXPECT_HR(hr, S_OK);
10835     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10836
10837     len = sizeof(buffW)/sizeof(WCHAR);
10838     buffW[0] = 0;
10839     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10840     EXPECT_HR(hr, E_FAIL);
10841
10842     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10843     EXPECT_HR(hr, E_POINTER);
10844
10845     b = VARIANT_FALSE;
10846     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10847     EXPECT_HR(hr, S_OK);
10848     ok(b == VARIANT_TRUE, "got %d\n", b);
10849
10850     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10851     EXPECT_HR(hr, S_OK);
10852
10853     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10854     EXPECT_HR(hr, S_OK);
10855
10856     len = sizeof(buffW)/sizeof(WCHAR);
10857     buffW[0] = 0;
10858     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10859     EXPECT_HR(hr, S_OK);
10860     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10861
10862     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10863     EXPECT_HR(hr, S_OK);
10864
10865     len = sizeof(buffW)/sizeof(WCHAR);
10866     buffW[0] = 0;
10867     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10868     EXPECT_HR(hr, S_OK);
10869     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10870
10871     len = sizeof(buffW)/sizeof(WCHAR);
10872     buffW[0] = 0;
10873     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10874     EXPECT_HR(hr, S_OK);
10875     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10876
10877     len = sizeof(buffW)/sizeof(WCHAR);
10878     buffW[0] = 0;
10879     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10880     EXPECT_HR(hr, S_OK);
10881     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10882
10883     /* new prefix placed at index 1 always */
10884     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10885     EXPECT_HR(hr, S_OK);
10886
10887     len = sizeof(buffW)/sizeof(WCHAR);
10888     buffW[0] = 0;
10889     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10890     EXPECT_HR(hr, S_OK);
10891     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10892
10893     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10894     todo_wine EXPECT_HR(hr, E_FAIL);
10895
10896     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10897     EXPECT_HR(hr, E_FAIL);
10898
10899     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10900     EXPECT_HR(hr, E_FAIL);
10901
10902     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10903     EXPECT_HR(hr, S_OK);
10904
10905     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10906     EXPECT_HR(hr, S_FALSE);
10907
10908     len = sizeof(buffW)/sizeof(WCHAR);
10909     buffW[0] = 0;
10910     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10911     EXPECT_HR(hr, S_OK);
10912     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10913
10914     len = sizeof(buffW)/sizeof(WCHAR);
10915     buffW[0] = 0;
10916     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10917     EXPECT_HR(hr, S_OK);
10918     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10919
10920     IMXNamespaceManager_Release(nsmgr);
10921
10922     free_bstrs();
10923 }
10924
10925 static const DOMNodeType nodetypes_test[] =
10926 {
10927     NODE_ELEMENT,
10928     NODE_ATTRIBUTE,
10929     NODE_TEXT,
10930     NODE_CDATA_SECTION,
10931     NODE_ENTITY_REFERENCE,
10932     NODE_PROCESSING_INSTRUCTION,
10933     NODE_COMMENT,
10934     NODE_DOCUMENT_FRAGMENT,
10935     NODE_INVALID
10936 };
10937
10938 static void test_dispex(void)
10939 {
10940     const DOMNodeType *type = nodetypes_test;
10941     IXMLDOMImplementation *impl;
10942     IXMLDOMNodeList *node_list;
10943     IXMLDOMParseError *error;
10944     IXMLDOMNamedNodeMap *map;
10945     IXSLProcessor *processor;
10946     IXSLTemplate *template;
10947     IXMLDOMDocument *doc;
10948     IXMLHTTPRequest *req;
10949     IXMLDOMElement *elem;
10950     IDispatchEx *dispex;
10951     IXMLDOMNode *node;
10952     VARIANT_BOOL b;
10953     IUnknown *unk;
10954     HRESULT hr;
10955     DISPID did;
10956
10957     doc = create_document(&IID_IXMLDOMDocument);
10958
10959     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10960     test_domobj_dispex(unk);
10961     IUnknown_Release(unk);
10962
10963     for(; *type != NODE_INVALID; type++)
10964     {
10965         IXMLDOMNode *node;
10966         VARIANT v;
10967
10968         V_VT(&v) = VT_I2;
10969         V_I2(&v) = *type;
10970
10971         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10972         ok(hr == S_OK, "failed to create node type %d\n", *type);
10973
10974         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10975
10976         test_domobj_dispex(unk);
10977         IUnknown_Release(unk);
10978         IXMLDOMNode_Release(node);
10979     }
10980
10981     /* IXMLDOMNodeList */
10982     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10983     EXPECT_HR(hr, S_OK);
10984     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10985     test_domobj_dispex(unk);
10986     IUnknown_Release(unk);
10987     IXMLDOMNodeList_Release(node_list);
10988
10989     /* IXMLDOMNodeList for children list */
10990     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10991     EXPECT_HR(hr, S_OK);
10992     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10993     test_domobj_dispex(unk);
10994     IUnknown_Release(unk);
10995
10996     /* collection dispex test, empty collection */
10997     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10998     EXPECT_HR(hr, S_OK);
10999     did = 0;
11000     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11001     EXPECT_HR(hr, S_OK);
11002     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11003     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11004     EXPECT_HR(hr, S_OK);
11005     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11006     IDispatchEx_Release(dispex);
11007
11008     IXMLDOMNodeList_Release(node_list);
11009
11010     /* IXMLDOMParseError */
11011     hr = IXMLDOMDocument_get_parseError(doc, &error);
11012     EXPECT_HR(hr, S_OK);
11013     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11014     test_domobj_dispex(unk);
11015     IUnknown_Release(unk);
11016     IXMLDOMParseError_Release(error);
11017
11018     /* IXMLDOMNamedNodeMap */
11019     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
11020     EXPECT_HR(hr, S_OK);
11021
11022     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11023     EXPECT_HR(hr, S_OK);
11024     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11025     EXPECT_HR(hr, S_OK);
11026     IXMLDOMNodeList_Release(node_list);
11027
11028     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11029     EXPECT_HR(hr, S_OK);
11030     IXMLDOMNode_Release(node);
11031     hr = IXMLDOMElement_get_attributes(elem, &map);
11032     EXPECT_HR(hr, S_OK);
11033     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11034     test_domobj_dispex(unk);
11035     IUnknown_Release(unk);
11036     /* collection dispex test */
11037     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11038     EXPECT_HR(hr, S_OK);
11039     did = 0;
11040     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11041     EXPECT_HR(hr, S_OK);
11042     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11043     IDispatchEx_Release(dispex);
11044
11045     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11046     EXPECT_HR(hr, S_OK);
11047     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11048     EXPECT_HR(hr, S_OK);
11049     IXMLDOMNodeList_Release(node_list);
11050     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11051     EXPECT_HR(hr, S_OK);
11052     IXMLDOMNode_Release(node);
11053     hr = IXMLDOMElement_get_attributes(elem, &map);
11054     EXPECT_HR(hr, S_OK);
11055     /* collection dispex test, empty collection */
11056     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11057     EXPECT_HR(hr, S_OK);
11058     did = 0;
11059     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11060     EXPECT_HR(hr, S_OK);
11061     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11062     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11063     EXPECT_HR(hr, S_OK);
11064     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11065     IDispatchEx_Release(dispex);
11066
11067     IXMLDOMNamedNodeMap_Release(map);
11068     IXMLDOMElement_Release(elem);
11069
11070     /* IXMLDOMImplementation */
11071     hr = IXMLDOMDocument_get_implementation(doc, &impl);
11072     EXPECT_HR(hr, S_OK);
11073
11074     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11075     EXPECT_HR(hr, S_OK);
11076     IDispatchEx_Release(dispex);
11077     IXMLDOMImplementation_Release(impl);
11078
11079     IXMLDOMDocument_Release(doc);
11080
11081     /* IXMLHTTPRequest */
11082     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11083         &IID_IXMLHttpRequest, (void**)&req);
11084     if (hr == S_OK)
11085     {
11086         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11087         EXPECT_HR(hr, E_NOINTERFACE);
11088         IXMLHTTPRequest_Release(req);
11089     }
11090
11091     /* IXSLTemplate */
11092     template = create_xsltemplate(&IID_IXSLTemplate);
11093     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11094     EXPECT_HR(hr, S_OK);
11095     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11096     EXPECT_HR(hr, S_OK);
11097     test_domobj_dispex(unk);
11098     IUnknown_Release(unk);
11099     IDispatchEx_Release(dispex);
11100
11101     /* IXSLProcessor */
11102     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11103     EXPECT_HR(hr, S_OK);
11104     b = VARIANT_FALSE;
11105     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11106     EXPECT_HR(hr, S_OK);
11107     ok(b == VARIANT_TRUE, "got %d\n", b);
11108
11109     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11110     EXPECT_HR(hr, S_OK);
11111     IXMLDOMDocument_Release(doc);
11112
11113     hr = IXSLTemplate_createProcessor(template, &processor);
11114     EXPECT_HR(hr, S_OK);
11115     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11116     EXPECT_HR(hr, S_OK);
11117     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11118     EXPECT_HR(hr, S_OK);
11119     test_domobj_dispex(unk);
11120     IUnknown_Release(unk);
11121     IDispatchEx_Release(dispex);
11122
11123     IXSLProcessor_Release(processor);
11124     IXSLTemplate_Release(template);
11125
11126     free_bstrs();
11127 }
11128
11129 static void test_parseerror(void)
11130 {
11131     IXMLDOMParseError2 *error2;
11132     IXMLDOMParseError *error;
11133     IXMLDOMDocument *doc;
11134     HRESULT hr;
11135
11136     doc = create_document(&IID_IXMLDOMDocument);
11137
11138     hr = IXMLDOMDocument_get_parseError(doc, &error);
11139     EXPECT_HR(hr, S_OK);
11140
11141     hr = IXMLDOMParseError_get_line(error, NULL);
11142     EXPECT_HR(hr, E_INVALIDARG);
11143
11144     hr = IXMLDOMParseError_get_srcText(error, NULL);
11145     EXPECT_HR(hr, E_INVALIDARG);
11146
11147     hr = IXMLDOMParseError_get_linepos(error, NULL);
11148     EXPECT_HR(hr, E_INVALIDARG);
11149
11150     IXMLDOMParseError_Release(error);
11151     IXMLDOMDocument_Release(doc);
11152
11153     doc = create_document_version(60, &IID_IXMLDOMDocument);
11154     if (!doc) return;
11155     hr = IXMLDOMDocument_get_parseError(doc, &error);
11156     EXPECT_HR(hr, S_OK);
11157     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11158     EXPECT_HR(hr, S_OK);
11159     IXMLDOMParseError2_Release(error2);
11160     IXMLDOMParseError_Release(error);
11161     IXMLDOMDocument_Release(doc);
11162 }
11163
11164 static void test_getAttributeNode(void)
11165 {
11166     IXMLDOMAttribute *attr;
11167     IXMLDOMDocument *doc;
11168     IXMLDOMElement *elem;
11169     VARIANT_BOOL v;
11170     HRESULT hr;
11171     BSTR str;
11172
11173     doc = create_document(&IID_IXMLDOMDocument);
11174
11175     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11176     EXPECT_HR(hr, S_OK);
11177
11178     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11179     EXPECT_HR(hr, S_OK);
11180
11181     str = SysAllocString(nonexistent_fileW);
11182     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11183     EXPECT_HR(hr, E_FAIL);
11184
11185     attr = (IXMLDOMAttribute*)0xdeadbeef;
11186     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11187     EXPECT_HR(hr, E_FAIL);
11188     ok(attr == NULL, "got %p\n", attr);
11189     SysFreeString(str);
11190
11191     str = SysAllocString(nonexistent_attrW);
11192     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11193     EXPECT_HR(hr, S_FALSE);
11194
11195     attr = (IXMLDOMAttribute*)0xdeadbeef;
11196     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11197     EXPECT_HR(hr, S_FALSE);
11198     ok(attr == NULL, "got %p\n", attr);
11199     SysFreeString(str);
11200
11201     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11202     EXPECT_HR(hr, S_OK);
11203     IXMLDOMAttribute_Release(attr);
11204
11205     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11206     EXPECT_HR(hr, S_FALSE);
11207
11208     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11209     EXPECT_HR(hr, S_OK);
11210     IXMLDOMAttribute_Release(attr);
11211
11212     IXMLDOMElement_Release(elem);
11213     IXMLDOMDocument_Release(doc);
11214     free_bstrs();
11215 }
11216
11217 typedef struct {
11218     DOMNodeType type;
11219     const char *name;
11220     REFIID iids[3];
11221 } supporterror_t;
11222
11223 static const supporterror_t supporterror_test[] = {
11224     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11225     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11226     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11227     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11228     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11229     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11230     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11231     { NODE_INVALID }
11232 };
11233
11234 static void test_supporterrorinfo(void)
11235 {
11236     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11237                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11238     const supporterror_t *ptr = supporterror_test;
11239     ISupportErrorInfo *errorinfo, *info2;
11240     IXMLDOMNamedNodeMap *map, *map2;
11241     IXMLDOMDocument *doc;
11242     IXMLDOMElement *elem;
11243     VARIANT_BOOL b;
11244     IUnknown *unk;
11245     REFIID *iid;
11246     void *dummy;
11247     HRESULT hr;
11248
11249     doc = create_document_version(60, &IID_IXMLDOMDocument3);
11250     if (!doc) return;
11251
11252     EXPECT_REF(doc, 1);
11253     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11254     EXPECT_HR(hr, S_OK);
11255     EXPECT_REF(doc, 1);
11256     ISupportErrorInfo_AddRef(errorinfo);
11257     EXPECT_REF(errorinfo, 2);
11258     EXPECT_REF(doc, 1);
11259     ISupportErrorInfo_Release(errorinfo);
11260
11261     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11262     EXPECT_HR(hr, S_OK);
11263     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11264
11265     /* error interface can't be queried back for DOM interface */
11266     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11267     EXPECT_HR(hr, E_NOINTERFACE);
11268     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11269     EXPECT_HR(hr, E_NOINTERFACE);
11270
11271     ISupportErrorInfo_Release(info2);
11272
11273     iid = iids;
11274     while (*iid)
11275     {
11276         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11277         EXPECT_HR(hr, S_OK);
11278         if (hr == S_OK)
11279         {
11280             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11281             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11282             IUnknown_Release(unk);
11283         }
11284
11285         iid++;
11286     }
11287
11288     ISupportErrorInfo_Release(errorinfo);
11289
11290     while (ptr->type != NODE_INVALID)
11291     {
11292         IXMLDOMNode *node;
11293         VARIANT type;
11294
11295         V_VT(&type) = VT_I1;
11296         V_I1(&type) = ptr->type;
11297
11298         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11299         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11300
11301         EXPECT_REF(node, 1);
11302         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11303         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11304         EXPECT_REF(node, 1);
11305
11306         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11307         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11308
11309         iid = ptr->iids;
11310
11311         while (*iid)
11312         {
11313             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11314             if (hr == S_OK)
11315             {
11316                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11317                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11318                 IUnknown_Release(unk);
11319             }
11320
11321             iid++;
11322         }
11323
11324         ISupportErrorInfo_Release(errorinfo);
11325         IXMLDOMNode_Release(node);
11326         ptr++;
11327     }
11328
11329     /* IXMLDOMNamedNodeMap */
11330     b = VARIANT_FALSE;
11331     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11332     EXPECT_HR(hr, S_OK);
11333     ok(b == VARIANT_TRUE, "got %d\n", b);
11334
11335     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11336     EXPECT_HR(hr, S_OK);
11337
11338     hr = IXMLDOMElement_get_attributes(elem, &map);
11339     EXPECT_HR(hr, S_OK);
11340
11341     EXPECT_REF(map, 1);
11342     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11343     EXPECT_HR(hr, S_OK);
11344     EXPECT_REF(map, 2);
11345
11346     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11347     EXPECT_HR(hr, S_OK);
11348
11349     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11350     EXPECT_HR(hr, S_OK);
11351     ok(map == map2, "got %p\n", map2);
11352     IXMLDOMNamedNodeMap_Release(map2);
11353
11354     EXPECT_REF(errorinfo, 2);
11355     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11356     EXPECT_HR(hr, S_OK);
11357     EXPECT_REF(errorinfo, 3);
11358     EXPECT_REF(map, 3);
11359     IUnknown_Release(unk);
11360
11361     ISupportErrorInfo_Release(errorinfo);
11362     IXMLDOMNamedNodeMap_Release(map);
11363     IXMLDOMElement_Release(elem);
11364
11365     IXMLDOMDocument_Release(doc);
11366     free_bstrs();
11367 }
11368
11369 typedef struct {
11370     DOMNodeType type;
11371     const char *name;
11372     const char *put_content;
11373     HRESULT put_hr;
11374     VARTYPE get_vt;
11375     HRESULT get_hr;
11376 } node_value_t;
11377
11378 static const node_value_t nodevalue_test[] = {
11379     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11380     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11381     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11382     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11383     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11384     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11385     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11386     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11387     { NODE_INVALID }
11388 };
11389
11390 static void test_nodeValue(void)
11391 {
11392     const node_value_t *ptr = nodevalue_test;
11393     IXMLDOMDocument *doc;
11394     HRESULT hr;
11395
11396     doc = create_document(&IID_IXMLDOMDocument);
11397     if (!doc) return;
11398
11399     while (ptr->type != NODE_INVALID)
11400     {
11401         IXMLDOMNode *node;
11402         VARIANT v;
11403
11404         V_VT(&v) = VT_I2;
11405         V_I2(&v) = ptr->type;
11406
11407         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11408         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11409
11410         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11411         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11412
11413         V_VT(&v) = VT_BSTR;
11414         V_BSTR(&v) = _bstr_(ptr->put_content);
11415         hr = IXMLDOMNode_put_nodeValue(node, v);
11416         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11417
11418         V_VT(&v) = VT_EMPTY;
11419         hr = IXMLDOMNode_get_nodeValue(node, &v);
11420         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11421         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11422         if (hr == S_OK)
11423             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11424                 wine_dbgstr_w(V_BSTR(&v)));
11425         VariantClear(&v);
11426
11427         IXMLDOMNode_Release(node);
11428
11429         ptr++;
11430     }
11431
11432     IXMLDOMDocument_Release(doc);
11433 }
11434
11435 static const char namespacesA[] =
11436 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11437 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11438 "     <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11439 "     <ns1:elem3/>"
11440 "     <ns1:elem4/>"
11441 "     <elem5 xmlns=\"http://blahblah.org\"/>"
11442 "     <ns1:elem6>true</ns1:elem6>"
11443 "   </ns1:elem1>";
11444
11445 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11446 static const char xsd_schema1_xml[] =
11447 "<?xml version='1.0'?>"
11448 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11449 "            targetNamespace='x-schema:test1.xsd'>"
11450 "   <element name='root'>"
11451 "       <complexType>"
11452 "           <sequence maxOccurs='unbounded'>"
11453 "               <any/>"
11454 "           </sequence>"
11455 "       </complexType>"
11456 "   </element>"
11457 "</schema>";
11458
11459 static void test_get_namespaces(void)
11460 {
11461     IXMLDOMSchemaCollection *collection, *collection2;
11462     IXMLDOMDocument2 *doc, *doc2;
11463     IEnumVARIANT *enumv;
11464     IXMLDOMNode *node;
11465     VARIANT_BOOL b;
11466     HRESULT hr;
11467     VARIANT v;
11468     LONG len;
11469     BSTR s;
11470
11471     doc = create_document(&IID_IXMLDOMDocument2);
11472     if (!doc) return;
11473
11474     /* null pointer */
11475     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11476     EXPECT_HR(hr, E_POINTER);
11477
11478     /* no document loaded */
11479     collection = (void*)0xdeadbeef;
11480     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11481     EXPECT_HR(hr, S_OK);
11482     if (hr != S_OK)
11483     {
11484         IXMLDOMDocument_Release(doc);
11485         return;
11486     }
11487     EXPECT_REF(collection, 2);
11488
11489     collection2 = (void*)0xdeadbeef;
11490     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11491     EXPECT_HR(hr, S_OK);
11492     ok(collection == collection2, "got %p\n", collection2);
11493     EXPECT_REF(collection, 3);
11494     IXMLDOMSchemaCollection_Release(collection);
11495
11496     len = -1;
11497     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11498     EXPECT_HR(hr, S_OK);
11499     ok(len == 0, "got %d\n", len);
11500     IXMLDOMSchemaCollection_Release(collection);
11501
11502     /* now with document */
11503     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11504     EXPECT_HR(hr, S_OK);
11505
11506     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11507     EXPECT_HR(hr, S_OK);
11508
11509     len = -1;
11510     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11511     EXPECT_HR(hr, S_OK);
11512     ok(len == 2, "got %d\n", len);
11513
11514     /* try to lookup some uris */
11515     node = (void*)0xdeadbeef;
11516     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11517     EXPECT_HR(hr, S_OK);
11518     ok(node == NULL, "got %p\n", node);
11519
11520     node = (void*)0xdeadbeef;
11521     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11522     EXPECT_HR(hr, S_OK);
11523     ok(node == NULL, "got %p\n", node);
11524
11525     /* load schema and try to add it */
11526     doc2 = create_document(&IID_IXMLDOMDocument2);
11527     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11528     EXPECT_HR(hr, S_OK);
11529
11530     V_VT(&v) = VT_DISPATCH;
11531     V_DISPATCH(&v) = (IDispatch*)doc2;
11532     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11533     EXPECT_HR(hr, E_FAIL);
11534
11535     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11536     EXPECT_HR(hr, S_OK);
11537     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11538     SysFreeString(s);
11539
11540     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11541     EXPECT_HR(hr, S_OK);
11542     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11543     SysFreeString(s);
11544
11545     s = (void*)0xdeadbeef;
11546     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11547     EXPECT_HR(hr, E_FAIL);
11548     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11549
11550     /* enumerate */
11551     enumv = (void*)0xdeadbeef;
11552     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11553 todo_wine
11554     EXPECT_HR(hr, S_OK);
11555     if (hr == S_OK)
11556     {
11557         ok(enumv != NULL, "got %p\n", enumv);
11558
11559         V_VT(&v) = VT_EMPTY;
11560         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11561         EXPECT_HR(hr, S_OK);
11562         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11563         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11564         VariantClear(&v);
11565
11566         V_VT(&v) = VT_EMPTY;
11567         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11568         EXPECT_HR(hr, S_OK);
11569         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11570         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11571         VariantClear(&v);
11572
11573         V_VT(&v) = VT_NULL;
11574         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11575         EXPECT_HR(hr, S_FALSE);
11576         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11577
11578         IEnumVARIANT_Release(enumv);
11579     }
11580     IXMLDOMSchemaCollection_Release(collection);
11581
11582     IXMLDOMDocument2_Release(doc);
11583
11584     /* now with CLSID_DOMDocument60 */
11585     doc = create_document_version(60, &IID_IXMLDOMDocument2);
11586     if (!doc) return;
11587
11588     /* null pointer */
11589     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11590     EXPECT_HR(hr, E_POINTER);
11591
11592     /* no document loaded */
11593     collection = (void*)0xdeadbeef;
11594     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11595     EXPECT_HR(hr, S_OK);
11596     if (hr != S_OK)
11597     {
11598         IXMLDOMDocument_Release(doc);
11599         return;
11600     }
11601     EXPECT_REF(collection, 2);
11602
11603     collection2 = (void*)0xdeadbeef;
11604     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11605     EXPECT_HR(hr, S_OK);
11606     ok(collection == collection2, "got %p\n", collection2);
11607     EXPECT_REF(collection, 3);
11608     IXMLDOMSchemaCollection_Release(collection);
11609
11610     len = -1;
11611     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11612     EXPECT_HR(hr, S_OK);
11613     ok(len == 0, "got %d\n", len);
11614     IXMLDOMSchemaCollection_Release(collection);
11615
11616     /* now with document */
11617     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11618     EXPECT_HR(hr, S_OK);
11619
11620     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11621     EXPECT_HR(hr, S_OK);
11622
11623     len = -1;
11624     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11625     EXPECT_HR(hr, S_OK);
11626     ok(len == 2, "got %d\n", len);
11627
11628     /* try to lookup some uris */
11629     node = (void*)0xdeadbeef;
11630     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11631     EXPECT_HR(hr, E_NOTIMPL);
11632     ok(node == (void*)0xdeadbeef, "got %p\n", node);
11633
11634     /* load schema and try to add it */
11635     doc2 = create_document(&IID_IXMLDOMDocument2);
11636     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11637     EXPECT_HR(hr, S_OK);
11638
11639     V_VT(&v) = VT_DISPATCH;
11640     V_DISPATCH(&v) = (IDispatch*)doc2;
11641     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11642     EXPECT_HR(hr, E_FAIL);
11643     IXMLDOMSchemaCollection_Release(doc2);
11644
11645     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11646     EXPECT_HR(hr, S_OK);
11647     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11648     SysFreeString(s);
11649
11650     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11651     EXPECT_HR(hr, S_OK);
11652     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11653     SysFreeString(s);
11654
11655     s = (void*)0xdeadbeef;
11656     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11657     EXPECT_HR(hr, E_FAIL);
11658     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11659
11660     /* enumerate */
11661     enumv = (void*)0xdeadbeef;
11662     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11663 todo_wine
11664     EXPECT_HR(hr, S_OK);
11665     if (hr == S_OK)
11666     {
11667         ok(enumv != NULL, "got %p\n", enumv);
11668
11669         V_VT(&v) = VT_EMPTY;
11670         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11671         EXPECT_HR(hr, S_OK);
11672         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11673         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11674         VariantClear(&v);
11675
11676         V_VT(&v) = VT_EMPTY;
11677         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11678         EXPECT_HR(hr, S_OK);
11679         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11680         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11681         VariantClear(&v);
11682
11683         V_VT(&v) = VT_NULL;
11684         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11685         EXPECT_HR(hr, S_FALSE);
11686         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11687
11688         IEnumVARIANT_Release(enumv);
11689     }
11690     IXMLDOMSchemaCollection_Release(collection);
11691     IXMLDOMDocument2_Release(doc);
11692     free_bstrs();
11693 }
11694
11695 static DOMNodeType put_data_types[] = {
11696     NODE_TEXT,
11697     NODE_CDATA_SECTION,
11698     NODE_PROCESSING_INSTRUCTION,
11699     NODE_COMMENT,
11700     NODE_INVALID
11701 };
11702
11703 static void test_put_data(void)
11704 {
11705     static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0};
11706     WCHAR buff[100], *data;
11707     IXMLDOMDocument *doc;
11708     DOMNodeType *type;
11709     BSTR get_data;
11710     HRESULT hr;
11711
11712     doc = create_document(&IID_IXMLDOMDocument);
11713     if (!doc) return;
11714
11715     memcpy(&buff[2], test_data, sizeof(test_data));
11716     /* just a big length */
11717     *(DWORD*)buff = 0xf0f0;
11718     data = &buff[2];
11719
11720     type = put_data_types;
11721     while (*type != NODE_INVALID)
11722     {
11723        IXMLDOMNode *node;
11724        VARIANT v;
11725
11726        V_VT(&v) = VT_I2;
11727        V_I2(&v) = *type;
11728
11729        hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
11730        EXPECT_HR(hr, S_OK);
11731
11732        /* put_data() is interface-specific */
11733        switch (*type)
11734        {
11735            case NODE_TEXT:
11736            {
11737               IXMLDOMText *text;
11738
11739               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
11740               EXPECT_HR(hr, S_OK);
11741               hr = IXMLDOMText_put_data(text, data);
11742               EXPECT_HR(hr, S_OK);
11743
11744               hr = IXMLDOMText_get_data(text, &get_data);
11745               EXPECT_HR(hr, S_OK);
11746
11747               IXMLDOMText_Release(text);
11748               break;
11749            }
11750            case NODE_CDATA_SECTION:
11751            {
11752               IXMLDOMCDATASection *cdata;
11753
11754               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
11755               EXPECT_HR(hr, S_OK);
11756               hr = IXMLDOMCDATASection_put_data(cdata, data);
11757               EXPECT_HR(hr, S_OK);
11758
11759               hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
11760               EXPECT_HR(hr, S_OK);
11761
11762               IXMLDOMCDATASection_Release(cdata);
11763               break;
11764            }
11765            case NODE_PROCESSING_INSTRUCTION:
11766            {
11767               IXMLDOMProcessingInstruction *pi;
11768
11769               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
11770               EXPECT_HR(hr, S_OK);
11771               hr = IXMLDOMProcessingInstruction_put_data(pi, data);
11772               EXPECT_HR(hr, S_OK);
11773
11774               hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
11775               EXPECT_HR(hr, S_OK);
11776
11777               IXMLDOMProcessingInstruction_Release(pi);
11778               break;
11779            }
11780            case NODE_COMMENT:
11781            {
11782               IXMLDOMComment *comment;
11783
11784               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
11785               EXPECT_HR(hr, S_OK);
11786               hr = IXMLDOMComment_put_data(comment, data);
11787               EXPECT_HR(hr, S_OK);
11788
11789               hr = IXMLDOMComment_get_data(comment, &get_data);
11790               EXPECT_HR(hr, S_OK);
11791
11792               IXMLDOMComment_Release(comment);
11793               break;
11794            }
11795            default:
11796               break;
11797        }
11798
11799        /* compare */
11800        ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
11801            wine_dbgstr_w(data));
11802        SysFreeString(get_data);
11803
11804        IXMLDOMNode_Release(node);
11805        type++;
11806     }
11807
11808     IXMLDOMDocument_Release(doc);
11809     free_bstrs();
11810 }
11811
11812 START_TEST(domdoc)
11813 {
11814     IXMLDOMDocument *doc;
11815     IUnknown *unk;
11816     HRESULT hr;
11817
11818     hr = CoInitialize( NULL );
11819     ok( hr == S_OK, "failed to init com\n");
11820     if (hr != S_OK) return;
11821
11822     test_XMLHTTP();
11823
11824     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
11825     if (hr != S_OK)
11826     {
11827         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
11828         return;
11829     }
11830
11831     IXMLDOMDocument_Release(doc);
11832
11833     test_domdoc();
11834     test_persiststreaminit();
11835     test_domnode();
11836     test_refs();
11837     test_create();
11838     test_getElementsByTagName();
11839     test_get_text();
11840     test_get_childNodes();
11841     test_get_firstChild();
11842     test_get_lastChild();
11843     test_removeChild();
11844     test_replaceChild();
11845     test_removeNamedItem();
11846     test_IXMLDOMDocument2();
11847     test_whitespace();
11848     test_XPath();
11849     test_XSLPattern();
11850     test_cloneNode();
11851     test_xmlTypes();
11852     test_save();
11853     test_testTransforms();
11854     test_namespaces();
11855     test_FormattingXML();
11856     test_nodeTypedValue();
11857     test_TransformWithLoadingLocalFile();
11858     test_put_nodeValue();
11859     test_document_IObjectSafety();
11860     test_splitText();
11861     test_getQualifiedItem();
11862     test_removeQualifiedItem();
11863     test_get_ownerDocument();
11864     test_setAttributeNode();
11865     test_put_dataType();
11866     test_createNode();
11867     test_get_prefix();
11868     test_default_properties();
11869     test_selectSingleNode();
11870     test_events();
11871     test_createProcessingInstruction();
11872     test_put_nodeTypedValue();
11873     test_get_xml();
11874     test_insertBefore();
11875     test_appendChild();
11876     test_get_doctype();
11877     test_get_tagName();
11878     test_get_dataType();
11879     test_get_nodeTypeString();
11880     test_get_attributes();
11881     test_selection();
11882     test_load();
11883     test_dispex();
11884     test_parseerror();
11885     test_getAttributeNode();
11886     test_supporterrorinfo();
11887     test_nodeValue();
11888     test_get_namespaces();
11889     test_put_data();
11890
11891     test_xsltemplate();
11892
11893     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11894         &IID_IMXNamespaceManager, (void**)&unk);
11895     if (hr == S_OK)
11896     {
11897         test_mxnamespacemanager();
11898         test_mxnamespacemanager_override();
11899
11900         IUnknown_Release(unk);
11901     }
11902     else
11903         win_skip("MXNamespaceManager is not available\n");
11904
11905     CoUninitialize();
11906 }