Release 1.4.1.
[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 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1407 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1408 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1409 "            </html>\n"
1410 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1411 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1412 "            </html>\n"
1413 "        </description>\n"
1414 "    </elem>\n"
1415 "\n"
1416 "    <elem>\n"
1417 "        <a>A2 field</a>\n"
1418 "        <b>B2 field</b>\n"
1419 "        <c type=\"old\">C2 field</c>\n"
1420 "    </elem>\n"
1421 "\n"
1422 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1423 "        <a>A3 field</a>\n"
1424 "        <b>B3 field</b>\n"
1425 "        <c>C3 field</c>\n"
1426 "    </elem>\n"
1427 "\n"
1428 "    <elem>\n"
1429 "        <a>A4 field</a>\n"
1430 "        <b>B4 field</b>\n"
1431 "        <foo:c>C4 field</foo:c>\n"
1432 "    </elem>\n"
1433 "</root>\n";
1434
1435 static const CHAR szNodeTypesXML[] =
1436 "<?xml version='1.0'?>"
1437 "<!-- comment node 0 -->"
1438 "<root id='0' depth='0'>"
1439 "   <!-- comment node 1 -->"
1440 "   text node 0"
1441 "   <x id='1' depth='1'>"
1442 "       <?foo value='PI for x'?>"
1443 "       <!-- comment node 2 -->"
1444 "       text node 1"
1445 "       <a id='3' depth='2'/>"
1446 "       <b id='4' depth='2'/>"
1447 "       <c id='5' depth='2'/>"
1448 "   </x>"
1449 "   <y id='2' depth='1'>"
1450 "       <?bar value='PI for y'?>"
1451 "       <!-- comment node 3 -->"
1452 "       text node 2"
1453 "       <a id='6' depth='2'/>"
1454 "       <b id='7' depth='2'/>"
1455 "       <c id='8' depth='2'/>"
1456 "   </y>"
1457 "</root>";
1458
1459 static const CHAR szTransformXML[] =
1460 "<?xml version=\"1.0\"?>\n"
1461 "<greeting>\n"
1462 "Hello World\n"
1463 "</greeting>";
1464
1465 static  const CHAR szTransformSSXML[] =
1466 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1467 "   <xsl:output method=\"html\"/>\n"
1468 "   <xsl:template match=\"/\">\n"
1469 "       <xsl:apply-templates select=\"greeting\"/>\n"
1470 "   </xsl:template>\n"
1471 "   <xsl:template match=\"greeting\">\n"
1472 "       <html>\n"
1473 "           <body>\n"
1474 "               <h1>\n"
1475 "                   <xsl:value-of select=\".\"/>\n"
1476 "               </h1>\n"
1477 "           </body>\n"
1478 "       </html>\n"
1479 "   </xsl:template>\n"
1480 "</xsl:stylesheet>";
1481
1482 static  const CHAR szTransformOutput[] =
1483 "<html><body><h1>"
1484 "Hello World"
1485 "</h1></body></html>";
1486
1487 static const CHAR szTypeValueXML[] =
1488 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1489 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1490 "   <string>Wine</string>\n"
1491 "   <string2 dt:dt=\"string\">String</string2>\n"
1492 "   <number dt:dt=\"number\">12.44</number>\n"
1493 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1494 "   <int dt:dt=\"int\">-13</int>\n"
1495 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1496 "   <bool dt:dt=\"boolean\">1</bool>\n"
1497 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1498 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1499 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1500 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1501 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1502 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1503 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1504 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1505 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1506 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1507 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1508 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1509 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1510 "   <float dt:dt=\"float\">41221.421</float>\n"
1511 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1512 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1513 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1514 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1515 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1516 "</root>";
1517
1518 static const CHAR szBasicTransformSSXMLPart1[] =
1519 "<?xml version=\"1.0\"?>"
1520 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1521 "<xsl:output method=\"html\"/>\n"
1522 "<xsl:template match=\"/\">"
1523 "<HTML><BODY><TABLE>"
1524 "        <xsl:apply-templates select='document(\"";
1525
1526 static const CHAR szBasicTransformSSXMLPart2[] =
1527 "\")/bottle/wine'>"
1528 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1529 "        </xsl:apply-templates>"
1530 "</TABLE></BODY></HTML>"
1531 "</xsl:template>"
1532 "<xsl:template match=\"bottle\">"
1533 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"name\">"
1536 "   <TD><xsl:apply-templates /></TD>"
1537 "</xsl:template>"
1538 "<xsl:template match=\"cost\">"
1539 "   <TD><xsl:apply-templates /></TD>"
1540 "</xsl:template>"
1541 "</xsl:stylesheet>";
1542
1543 static const CHAR szBasicTransformXML[] =
1544 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1545
1546 static const CHAR szBasicTransformOutput[] =
1547 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1548
1549 #define SZ_EMAIL_DTD \
1550 "<!DOCTYPE email ["\
1551 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1552 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1553 "       <!ATTLIST email sent (yes|no) \"no\">"\
1554 "   <!ELEMENT recipients    (to+,cc*)>"\
1555 "   <!ELEMENT to            (#PCDATA)>"\
1556 "       <!ATTLIST to name CDATA #IMPLIED>"\
1557 "   <!ELEMENT cc            (#PCDATA)>"\
1558 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1559 "   <!ELEMENT from          (#PCDATA)>"\
1560 "       <!ATTLIST from name CDATA #IMPLIED>"\
1561 "   <!ELEMENT reply-to      (#PCDATA)>"\
1562 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1563 "   <!ELEMENT subject       ANY>"\
1564 "   <!ELEMENT body          ANY>"\
1565 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1566 "   <!ELEMENT attachment    (#PCDATA)>"\
1567 "       <!ATTLIST attachment id ID #REQUIRED>"\
1568 "]>"
1569
1570 static const CHAR szEmailXML[] =
1571 "<?xml version=\"1.0\"?>"
1572 SZ_EMAIL_DTD
1573 "<email attachments=\"patch1\">"
1574 "   <recipients>"
1575 "       <to>wine-patches@winehq.org</to>"
1576 "   </recipients>"
1577 "   <from name=\"Anonymous\">user@localhost</from>"
1578 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1579 "   <body>"
1580 "       It no longer causes spontaneous combustion..."
1581 "   </body>"
1582 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1583 "</email>";
1584
1585 static const CHAR szEmailXML_0D[] =
1586 "<?xml version=\"1.0\"?>"
1587 SZ_EMAIL_DTD
1588 "<email attachments=\"patch1\">"
1589 "   <recipients>"
1590 "       <to>wine-patches@winehq.org</to>"
1591 "   </recipients>"
1592 "   <from name=\"Anonymous\">user@localhost</from>"
1593 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1594 "   <body>"
1595 "       <undecl />"
1596 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1597 "   </body>"
1598 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1599 "</email>";
1600
1601 static const CHAR szEmailXML_0E[] =
1602 "<?xml version=\"1.0\"?>"
1603 SZ_EMAIL_DTD
1604 "<email attachments=\"patch1\">"
1605 "   <recipients>"
1606 "       <to>wine-patches@winehq.org</to>"
1607 "   </recipients>"
1608 "   <from name=\"Anonymous\">user@localhost</from>"
1609 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1610 "   <body>"
1611 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1612 "   </body>"
1613 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1614 "</email>";
1615
1616 static const CHAR szEmailXML_11[] =
1617 "<?xml version=\"1.0\"?>"
1618 SZ_EMAIL_DTD
1619 "<email attachments=\"patch1\">"
1620 "   <recipients>"
1621 "   </recipients>"
1622 "   <from name=\"Anonymous\">user@localhost</from>"
1623 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1624 "   <body>"
1625 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1626 "   </body>"
1627 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1628 "</email>";
1629
1630 static const CHAR szEmailXML_13[] =
1631 "<?xml version=\"1.0\"?>"
1632 SZ_EMAIL_DTD
1633 "<msg attachments=\"patch1\">"
1634 "   <recipients>"
1635 "       <to>wine-patches@winehq.org</to>"
1636 "   </recipients>"
1637 "   <from name=\"Anonymous\">user@localhost</from>"
1638 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1639 "   <body>"
1640 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1641 "   </body>"
1642 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1643 "</msg>";
1644
1645 static const CHAR szEmailXML_14[] =
1646 "<?xml version=\"1.0\"?>"
1647 SZ_EMAIL_DTD
1648 "<email attachments=\"patch1\">"
1649 "   <to>wine-patches@winehq.org</to>"
1650 "   <from name=\"Anonymous\">user@localhost</from>"
1651 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1652 "   <body>"
1653 "       XML_INVALID_CONTENT 0xC00CE014"
1654 "   </body>"
1655 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1656 "</email>";
1657
1658 static const CHAR szEmailXML_15[] =
1659 "<?xml version=\"1.0\"?>"
1660 SZ_EMAIL_DTD
1661 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1662 "   <recipients>"
1663 "       <to>wine-patches@winehq.org</to>"
1664 "   </recipients>"
1665 "   <from name=\"Anonymous\">user@localhost</from>"
1666 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1667 "   <body>"
1668 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1669 "   </body>"
1670 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1671 "</email>";
1672
1673 static const CHAR szEmailXML_16[] =
1674 "<?xml version=\"1.0\"?>"
1675 SZ_EMAIL_DTD
1676 "<email attachments=\"patch1\">"
1677 "   <recipients>"
1678 "       <to>wine-patches@winehq.org</to>"
1679 "   </recipients>"
1680 "   <from name=\"Anonymous\">user@localhost</from>"
1681 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1682 "   <body enc=\"ASCII\">"
1683 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1684 "   </body>"
1685 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1686 "</email>";
1687
1688 static const CHAR szEmailXML_17[] =
1689 "<?xml version=\"1.0\"?>"
1690 SZ_EMAIL_DTD
1691 "<email attachments=\"patch1\" sent=\"true\">"
1692 "   <recipients>"
1693 "       <to>wine-patches@winehq.org</to>"
1694 "   </recipients>"
1695 "   <from name=\"Anonymous\">user@localhost</from>"
1696 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1697 "   <body>"
1698 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1699 "   </body>"
1700 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1701 "</email>";
1702
1703 static const CHAR szEmailXML_18[] =
1704 "<?xml version=\"1.0\"?>"
1705 SZ_EMAIL_DTD
1706 "<email attachments=\"patch1\">"
1707 "   oops"
1708 "   <recipients>"
1709 "       <to>wine-patches@winehq.org</to>"
1710 "   </recipients>"
1711 "   <from name=\"Anonymous\">user@localhost</from>"
1712 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1713 "   <body>"
1714 "       XML_ILLEGAL_TEXT 0xC00CE018"
1715 "   </body>"
1716 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1717 "</email>";
1718
1719 static const CHAR szEmailXML_20[] =
1720 "<?xml version=\"1.0\"?>"
1721 SZ_EMAIL_DTD
1722 "<email>"
1723 "   <recipients>"
1724 "       <to>wine-patches@winehq.org</to>"
1725 "   </recipients>"
1726 "   <from name=\"Anonymous\">user@localhost</from>"
1727 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1728 "   <body>"
1729 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1730 "   </body>"
1731 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1732 "</email>";
1733
1734 static const char xpath_simple_list[] =
1735 "<?xml version=\"1.0\"?>"
1736 "<root>"
1737 "   <a attr1=\"1\" attr2=\"2\" />"
1738 "   <b/>"
1739 "   <c/>"
1740 "   <d/>"
1741 "</root>";
1742
1743 static const char default_ns_doc[] = {
1744     "<?xml version=\"1.0\"?>"
1745     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1746     "    d=\"d attr\" />"
1747 };
1748
1749 static const WCHAR nonexistent_fileW[] = {
1750     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1751 };
1752 static const WCHAR nonexistent_attrW[] = {
1753     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1754 };
1755 static const WCHAR szDocument[] = {
1756     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1757 };
1758
1759 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1760 static WCHAR szdl[] = { 'd','l',0 };
1761 static const WCHAR szvr[] = { 'v','r',0 };
1762 static const WCHAR szlc[] = { 'l','c',0 };
1763 static WCHAR szbs[] = { 'b','s',0 };
1764 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1765 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1766 static const WCHAR szstar[] = { '*',0 };
1767 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1768
1769 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1770 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1771 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1772
1773 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1774 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1775 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1776 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1777                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1778 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1779                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1780
1781 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1782 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1783
1784 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1785                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1786 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1787                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1788                              '!',']',']','>',0};
1789 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1790 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1791
1792 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1793 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1794 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1795
1796 #define expect_bstr_eq_and_free(bstr, expect) { \
1797     BSTR bstrExp = alloc_str_from_narrow(expect); \
1798     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1799     SysFreeString(bstr); \
1800     SysFreeString(bstrExp); \
1801 }
1802
1803 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1804
1805 #define ole_check(expr) { \
1806     HRESULT r = expr; \
1807     ok(r == S_OK, #expr " returned %x\n", r); \
1808 }
1809
1810 #define ole_expect(expr, expect) { \
1811     HRESULT r = expr; \
1812     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1813 }
1814
1815 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1816
1817 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1818 {
1819     void *obj = NULL;
1820     HRESULT hr;
1821
1822     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1823     if (hr != S_OK)
1824         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1825
1826     return obj;
1827 }
1828
1829 #define _create(cls) cls, #cls
1830
1831 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1832 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1833 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1834 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1835 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1836
1837 static BSTR alloc_str_from_narrow(const char *str)
1838 {
1839     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1840     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1841     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1842     return ret;
1843 }
1844
1845 static BSTR alloced_bstrs[256];
1846 static int alloced_bstrs_count;
1847
1848 static BSTR _bstr_(const char *str)
1849 {
1850     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1851     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1852     return alloced_bstrs[alloced_bstrs_count++];
1853 }
1854
1855 static void free_bstrs(void)
1856 {
1857     int i;
1858     for (i = 0; i < alloced_bstrs_count; i++)
1859         SysFreeString(alloced_bstrs[i]);
1860     alloced_bstrs_count = 0;
1861 }
1862
1863 static VARIANT _variantbstr_(const char *str)
1864 {
1865     VARIANT v;
1866     V_VT(&v) = VT_BSTR;
1867     V_BSTR(&v) = _bstr_(str);
1868     return v;
1869 }
1870
1871 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1872 {
1873     for (;;)
1874     {
1875         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1876         while (*sRight == '\r' || *sRight == '\n') sRight++;
1877         if (*sLeft != *sRight) return FALSE;
1878         if (!*sLeft) return TRUE;
1879         sLeft++;
1880         sRight++;
1881     }
1882 }
1883
1884 static void get_str_for_type(DOMNodeType type, char *buf)
1885 {
1886     switch (type)
1887     {
1888         case NODE_ATTRIBUTE:
1889             strcpy(buf, "A");
1890             break;
1891         case NODE_ELEMENT:
1892             strcpy(buf, "E");
1893             break;
1894         case NODE_DOCUMENT:
1895             strcpy(buf, "D");
1896             break;
1897         case NODE_TEXT:
1898             strcpy(buf, "T");
1899             break;
1900         case NODE_COMMENT:
1901             strcpy(buf, "C");
1902             break;
1903         case NODE_PROCESSING_INSTRUCTION:
1904             strcpy(buf, "P");
1905             break;
1906         default:
1907             wsprintfA(buf, "[%d]", type);
1908     }
1909 }
1910
1911 static int get_node_position(IXMLDOMNode *node)
1912 {
1913     HRESULT r;
1914     int pos = 0;
1915
1916     IXMLDOMNode_AddRef(node);
1917     do
1918     {
1919         IXMLDOMNode *new_node;
1920
1921         pos++;
1922         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1923         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1924         IXMLDOMNode_Release(node);
1925         node = new_node;
1926     } while (r == S_OK);
1927     return pos;
1928 }
1929
1930 static void node_to_string(IXMLDOMNode *node, char *buf)
1931 {
1932     HRESULT r = S_OK;
1933     DOMNodeType type;
1934
1935     if (node == NULL)
1936     {
1937         lstrcpyA(buf, "(null)");
1938         return;
1939     }
1940
1941     IXMLDOMNode_AddRef(node);
1942     while (r == S_OK)
1943     {
1944         IXMLDOMNode *new_node;
1945
1946         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1947         get_str_for_type(type, buf);
1948         buf+=strlen(buf);
1949
1950         if (type == NODE_ATTRIBUTE)
1951         {
1952             BSTR bstr;
1953             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1954             *(buf++) = '\'';
1955             wsprintfA(buf, "%ws", bstr);
1956             buf += strlen(buf);
1957             *(buf++) = '\'';
1958             SysFreeString(bstr);
1959
1960             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1961         }
1962         else
1963         {
1964             r = IXMLDOMNode_get_parentNode(node, &new_node);
1965             wsprintf(buf, "%d", get_node_position(node));
1966             buf += strlen(buf);
1967         }
1968
1969         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1970         IXMLDOMNode_Release(node);
1971         node = new_node;
1972         if (r == S_OK)
1973             *(buf++) = '.';
1974     }
1975
1976     *buf = 0;
1977 }
1978
1979 static char *list_to_string(IXMLDOMNodeList *list)
1980 {
1981     static char buf[4096];
1982     char *pos = buf;
1983     LONG len = 0;
1984     int i;
1985
1986     if (list == NULL)
1987     {
1988         lstrcpyA(buf, "(null)");
1989         return buf;
1990     }
1991     ole_check(IXMLDOMNodeList_get_length(list, &len));
1992     for (i = 0; i < len; i++)
1993     {
1994         IXMLDOMNode *node;
1995         if (i > 0)
1996             *(pos++) = ' ';
1997         ole_check(IXMLDOMNodeList_nextNode(list, &node));
1998         node_to_string(node, pos);
1999         pos += strlen(pos);
2000         IXMLDOMNode_Release(node);
2001     }
2002     *pos = 0;
2003     return buf;
2004 }
2005
2006 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
2007 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
2008
2009 struct docload_ret_t {
2010     VARIANT_BOOL b;
2011     HRESULT hr;
2012 };
2013
2014 struct leading_spaces_t {
2015     const CLSID *clsid;
2016     const char *name;
2017     struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
2018 };
2019
2020 static const struct leading_spaces_t leading_spaces_classdata[] = {
2021     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2022     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2023     { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2024     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2025     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2026     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2027     { NULL }
2028 };
2029
2030 static const char* leading_spaces_xmldata[] = {
2031     "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
2032     " <?xml version=\"1.0\"?><root/>",
2033     "\n<?xml version=\"1.0\"?><root/>",
2034     "\t<?xml version=\"1.0\"?><root/>",
2035     "\r\n<?xml version=\"1.0\"?><root/>",
2036     "\r<?xml version=\"1.0\"?><root/>",
2037     "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
2038     0
2039 };
2040
2041 static void test_domdoc( void )
2042 {
2043     HRESULT r, hr;
2044     IXMLDOMDocument *doc;
2045     IXMLDOMParseError *error;
2046     IXMLDOMElement *element = NULL;
2047     IXMLDOMNode *node;
2048     IXMLDOMText *nodetext = NULL;
2049     IXMLDOMComment *node_comment = NULL;
2050     IXMLDOMAttribute *node_attr = NULL;
2051     IXMLDOMNode *nodeChild = NULL;
2052     IXMLDOMProcessingInstruction *nodePI = NULL;
2053     const struct leading_spaces_t *class_ptr;
2054     const char **data_ptr;
2055     VARIANT_BOOL b;
2056     VARIANT var;
2057     BSTR str;
2058     LONG code, ref;
2059     LONG nLength = 0;
2060     WCHAR buff[100];
2061     int index;
2062
2063     /* Load document with leading spaces
2064      *
2065      * Test all CLSIDs with all test data XML strings
2066      */
2067     class_ptr = leading_spaces_classdata;
2068     index = 0;
2069     while (class_ptr->clsid)
2070     {
2071         HRESULT hr;
2072         int i;
2073
2074         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
2075              &IID_IXMLDOMDocument, (void**)&doc);
2076         if (hr != S_OK) {
2077             win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
2078             class_ptr++;
2079             index++;
2080             continue;
2081         }
2082
2083         data_ptr = leading_spaces_xmldata;
2084         i = 0;
2085         while (*data_ptr) {
2086             BSTR data = _bstr_(*data_ptr);
2087
2088             b = 0xc;
2089             V_VT(&var) = VT_BSTR;
2090             V_BSTR(&var) = data;
2091             hr = IXMLDOMDocument_load(doc, var, &b);
2092             EXPECT_HR(hr, class_ptr->ret[0].hr);
2093             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
2094
2095             b = 0xc;
2096             hr = IXMLDOMDocument_loadXML(doc, data, &b);
2097             EXPECT_HR(hr, class_ptr->ret[1].hr);
2098             ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
2099
2100             data_ptr++;
2101             i++;
2102         }
2103         class_ptr++;
2104         index++;
2105     }
2106
2107     doc = create_document(&IID_IXMLDOMDocument);
2108     if (!doc) return;
2109
2110 if (0)
2111 {
2112     /* crashes on native */
2113     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2114 }
2115
2116     /* try some stupid things */
2117     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2118     EXPECT_HR(hr, S_FALSE);
2119
2120     b = VARIANT_TRUE;
2121     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2122     EXPECT_HR(hr, S_FALSE);
2123     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2124
2125     /* try to load a document from a nonexistent file */
2126     b = VARIANT_TRUE;
2127     str = SysAllocString( nonexistent_fileW );
2128     VariantInit(&var);
2129     V_VT(&var) = VT_BSTR;
2130     V_BSTR(&var) = str;
2131
2132     r = IXMLDOMDocument_load( doc, var, &b);
2133     ok( r == S_FALSE, "loadXML succeeded\n");
2134     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2135     SysFreeString( str );
2136
2137     /* try load an empty document */
2138     b = VARIANT_TRUE;
2139     str = SysAllocString( szEmpty );
2140     r = IXMLDOMDocument_loadXML( doc, str, &b );
2141     ok( r == S_FALSE, "loadXML succeeded\n");
2142     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2143     SysFreeString( str );
2144
2145     r = IXMLDOMDocument_get_async( doc, &b );
2146     ok( r == S_OK, "get_async failed (%08x)\n", r);
2147     ok( b == VARIANT_TRUE, "Wrong default value\n");
2148
2149     /* check that there's no document element */
2150     element = NULL;
2151     r = IXMLDOMDocument_get_documentElement( doc, &element );
2152     ok( r == S_FALSE, "should be no document element\n");
2153
2154     /* try finding a node */
2155     node = NULL;
2156     str = SysAllocString( szstr1 );
2157     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2158     ok( r == S_FALSE, "ret %08x\n", r );
2159     SysFreeString( str );
2160
2161     b = VARIANT_TRUE;
2162     str = SysAllocString( szIncomplete );
2163     r = IXMLDOMDocument_loadXML( doc, str, &b );
2164     ok( r == S_FALSE, "loadXML succeeded\n");
2165     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2166     SysFreeString( str );
2167
2168     /* check that there's no document element */
2169     element = (IXMLDOMElement*)1;
2170     r = IXMLDOMDocument_get_documentElement( doc, &element );
2171     ok( r == S_FALSE, "should be no document element\n");
2172     ok( element == NULL, "Element should be NULL\n");
2173
2174     /* test for BSTR handling, pass broken BSTR */
2175     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2176     /* just a big length */
2177     *(DWORD*)buff = 0xf0f0;
2178     b = VARIANT_FALSE;
2179     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2180     ok( r == S_OK, "loadXML failed\n");
2181     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2182
2183     /* loadXML ignores the encoding attribute and always expects Unicode */
2184     b = VARIANT_FALSE;
2185     str = SysAllocString( szComplete6 );
2186     r = IXMLDOMDocument_loadXML( doc, str, &b );
2187     ok( r == S_OK, "loadXML failed\n");
2188     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2189     SysFreeString( str );
2190
2191     /* try a BSTR containing a Windows-1252 document */
2192     b = VARIANT_TRUE;
2193     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2194     r = IXMLDOMDocument_loadXML( doc, str, &b );
2195     ok( r == S_FALSE, "loadXML succeeded\n");
2196     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2197     SysFreeString( str );
2198
2199     /* try to load something valid */
2200     b = VARIANT_FALSE;
2201     str = SysAllocString( szComplete1 );
2202     r = IXMLDOMDocument_loadXML( doc, str, &b );
2203     ok( r == S_OK, "loadXML failed\n");
2204     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2205     SysFreeString( str );
2206
2207     /* check if nodename is correct */
2208     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2209     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2210
2211     str = (BSTR)0xdeadbeef;
2212     r = IXMLDOMDocument_get_baseName( doc, &str );
2213     ok ( r == S_FALSE, "got 0x%08x\n", r);
2214     ok (str == NULL, "got %p\n", str);
2215
2216     /* content doesn't matter here */
2217     str = NULL;
2218     r = IXMLDOMDocument_get_nodeName( doc, &str );
2219     ok ( r == S_OK, "get_nodeName wrong code\n");
2220     ok ( str != NULL, "str is null\n");
2221     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2222     SysFreeString( str );
2223
2224     /* test put_text */
2225     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2226     ok( r == E_FAIL, "ret %08x\n", r );
2227
2228     /* check that there's a document element */
2229     element = NULL;
2230     r = IXMLDOMDocument_get_documentElement( doc, &element );
2231     ok( r == S_OK, "should be a document element\n");
2232     if( element )
2233     {
2234         IObjectIdentity *ident;
2235
2236         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2237         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2238
2239         IXMLDOMElement_Release( element );
2240         element = NULL;
2241     }
2242
2243     /* as soon as we call loadXML again, the document element will disappear */
2244     b = 2;
2245     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2246     ok( r == S_FALSE, "loadXML failed\n");
2247     ok( b == 2, "variant modified\n");
2248     r = IXMLDOMDocument_get_documentElement( doc, &element );
2249     ok( r == S_FALSE, "should be no document element\n");
2250
2251     /* try to load something else simple and valid */
2252     b = VARIANT_FALSE;
2253     str = SysAllocString( szComplete3 );
2254     r = IXMLDOMDocument_loadXML( doc, str, &b );
2255     ok( r == S_OK, "loadXML failed\n");
2256     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2257     SysFreeString( str );
2258
2259     /* try something a little more complicated */
2260     b = FALSE;
2261     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2262     ok( r == S_OK, "loadXML failed\n");
2263     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2264
2265     r = IXMLDOMDocument_get_parseError( doc, &error );
2266     ok( r == S_OK, "returns %08x\n", r );
2267
2268     r = IXMLDOMParseError_get_errorCode( error, &code );
2269     ok( r == S_FALSE, "returns %08x\n", r );
2270     ok( code == 0, "code %d\n", code );
2271     IXMLDOMParseError_Release( error );
2272
2273     /* test createTextNode */
2274     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2275     ok( r == S_OK, "returns %08x\n", r );
2276     IXMLDOMText_Release(nodetext);
2277
2278     str = SysAllocString( szOpen );
2279     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2280     ok( r == E_INVALIDARG, "returns %08x\n", r );
2281     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2282     ok( r == S_OK, "returns %08x\n", r );
2283     SysFreeString( str );
2284     if(nodetext)
2285     {
2286         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2287         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2288
2289         /* Text Last Child Checks */
2290         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2291         ok(r == E_INVALIDARG, "ret %08x\n", r );
2292
2293         nodeChild = (IXMLDOMNode*)0x1;
2294         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2295         ok(r == S_FALSE, "ret %08x\n", r );
2296         ok(nodeChild == NULL, "nodeChild not NULL\n");
2297
2298         /* test length property */
2299         r = IXMLDOMText_get_length(nodetext, NULL);
2300         ok(r == E_INVALIDARG, "ret %08x\n", r );
2301
2302         r = IXMLDOMText_get_length(nodetext, &nLength);
2303         ok(r == S_OK, "ret %08x\n", r );
2304         ok(nLength == 4, "expected 4 got %d\n", nLength);
2305
2306         /* put data Tests */
2307         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2308         ok(r == S_OK, "ret %08x\n", r );
2309
2310         /* get data Tests */
2311         r = IXMLDOMText_get_data(nodetext, &str);
2312         ok(r == S_OK, "ret %08x\n", r );
2313         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2314         SysFreeString(str);
2315
2316         /* Confirm XML text is good */
2317         r = IXMLDOMText_get_xml(nodetext, &str);
2318         ok(r == S_OK, "ret %08x\n", r );
2319         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2320         SysFreeString(str);
2321
2322         /* Confirm we get the put_data Text back */
2323         r = IXMLDOMText_get_text(nodetext, &str);
2324         ok(r == S_OK, "ret %08x\n", r );
2325         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2326         SysFreeString(str);
2327
2328         /* test substringData */
2329         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2330         ok(r == E_INVALIDARG, "ret %08x\n", r );
2331
2332         /* test substringData - Invalid offset */
2333         str = (BSTR)&szElement;
2334         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2335         ok(r == E_INVALIDARG, "ret %08x\n", r );
2336         ok( str == NULL, "incorrect string\n");
2337
2338         /* test substringData - Invalid offset */
2339         str = (BSTR)&szElement;
2340         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2341         ok(r == S_FALSE, "ret %08x\n", r );
2342         ok( str == NULL, "incorrect string\n");
2343
2344         /* test substringData - Invalid size */
2345         str = (BSTR)&szElement;
2346         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2347         ok(r == E_INVALIDARG, "ret %08x\n", r );
2348         ok( str == NULL, "incorrect string\n");
2349
2350         /* test substringData - Invalid size */
2351         str = (BSTR)&szElement;
2352         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2353         ok(r == S_FALSE, "ret %08x\n", r );
2354         ok( str == NULL, "incorrect string\n");
2355
2356         /* test substringData - Start of string */
2357         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2358         ok(r == S_OK, "ret %08x\n", r );
2359         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2360         SysFreeString(str);
2361
2362         /* test substringData - Middle of string */
2363         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2364         ok(r == S_OK, "ret %08x\n", r );
2365         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2366         SysFreeString(str);
2367
2368         /* test substringData - End of string */
2369         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2370         ok(r == S_OK, "ret %08x\n", r );
2371         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2372         SysFreeString(str);
2373
2374         /* test appendData */
2375         r = IXMLDOMText_appendData(nodetext, NULL);
2376         ok(r == S_OK, "ret %08x\n", r );
2377
2378         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2379         ok(r == S_OK, "ret %08x\n", r );
2380
2381         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2382         ok(r == S_OK, "ret %08x\n", r );
2383
2384         r = IXMLDOMText_get_text(nodetext, &str);
2385         ok(r == S_OK, "ret %08x\n", r );
2386         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2387         SysFreeString(str);
2388
2389         /* test insertData */
2390         str = SysAllocStringLen(NULL, 0);
2391         r = IXMLDOMText_insertData(nodetext, -1, str);
2392         ok(r == S_OK, "ret %08x\n", r );
2393
2394         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2395         ok(r == S_OK, "ret %08x\n", r );
2396
2397         r = IXMLDOMText_insertData(nodetext, 1000, str);
2398         ok(r == S_OK, "ret %08x\n", r );
2399
2400         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2401         ok(r == S_OK, "ret %08x\n", r );
2402
2403         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2404         ok(r == S_OK, "ret %08x\n", r );
2405
2406         r = IXMLDOMText_insertData(nodetext, 0, str);
2407         ok(r == S_OK, "ret %08x\n", r );
2408         SysFreeString(str);
2409
2410         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2411         ok(r == E_INVALIDARG, "ret %08x\n", r );
2412
2413         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2414         ok(r == E_INVALIDARG, "ret %08x\n", r );
2415
2416         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2417         ok(r == S_OK, "ret %08x\n", r );
2418
2419         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2420         ok(r == S_OK, "ret %08x\n", r );
2421
2422         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2423         ok(r == S_OK, "ret %08x\n", r );
2424
2425         r = IXMLDOMText_get_text(nodetext, &str);
2426         ok(r == S_OK, "ret %08x\n", r );
2427         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2428         SysFreeString(str);
2429
2430         /* delete data */
2431         /* invalid arguments */
2432         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2433         ok(r == E_INVALIDARG, "ret %08x\n", r );
2434
2435         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2436         ok(r == S_OK, "ret %08x\n", r );
2437
2438         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2439         ok(r == E_INVALIDARG, "ret %08x\n", r );
2440
2441         r = IXMLDOMText_get_length(nodetext, &nLength);
2442         ok(r == S_OK, "ret %08x\n", r );
2443         ok(nLength == 43, "expected 43 got %d\n", nLength);
2444
2445         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2446         ok(r == S_OK, "ret %08x\n", r );
2447
2448         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2449         ok(r == E_INVALIDARG, "ret %08x\n", r );
2450
2451         /* delete from start */
2452         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2453         ok(r == S_OK, "ret %08x\n", r );
2454
2455         r = IXMLDOMText_get_length(nodetext, &nLength);
2456         ok(r == S_OK, "ret %08x\n", r );
2457         ok(nLength == 38, "expected 38 got %d\n", nLength);
2458
2459         r = IXMLDOMText_get_text(nodetext, &str);
2460         ok(r == S_OK, "ret %08x\n", r );
2461         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2462         SysFreeString(str);
2463
2464         /* delete from end */
2465         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2466         ok(r == S_OK, "ret %08x\n", r );
2467
2468         r = IXMLDOMText_get_length(nodetext, &nLength);
2469         ok(r == S_OK, "ret %08x\n", r );
2470         ok(nLength == 35, "expected 35 got %d\n", nLength);
2471
2472         r = IXMLDOMText_get_text(nodetext, &str);
2473         ok(r == S_OK, "ret %08x\n", r );
2474         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2475         SysFreeString(str);
2476
2477         /* delete from inside */
2478         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2479         ok(r == S_OK, "ret %08x\n", r );
2480
2481         r = IXMLDOMText_get_length(nodetext, &nLength);
2482         ok(r == S_OK, "ret %08x\n", r );
2483         ok(nLength == 2, "expected 2 got %d\n", nLength);
2484
2485         r = IXMLDOMText_get_text(nodetext, &str);
2486         ok(r == S_OK, "ret %08x\n", r );
2487         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2488         SysFreeString(str);
2489
2490         /* delete whole data ... */
2491         r = IXMLDOMText_get_length(nodetext, &nLength);
2492         ok(r == S_OK, "ret %08x\n", r );
2493
2494         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2495         ok(r == S_OK, "ret %08x\n", r );
2496         /* ... and try again with empty string */
2497         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2498         ok(r == S_OK, "ret %08x\n", r );
2499
2500         /* test put_data */
2501         V_VT(&var) = VT_BSTR;
2502         V_BSTR(&var) = SysAllocString(szstr1);
2503         r = IXMLDOMText_put_nodeValue(nodetext, var);
2504         ok(r == S_OK, "ret %08x\n", r );
2505         VariantClear(&var);
2506
2507         r = IXMLDOMText_get_text(nodetext, &str);
2508         ok(r == S_OK, "ret %08x\n", r );
2509         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2510         SysFreeString(str);
2511
2512         /* test put_data */
2513         V_VT(&var) = VT_I4;
2514         V_I4(&var) = 99;
2515         r = IXMLDOMText_put_nodeValue(nodetext, var);
2516         ok(r == S_OK, "ret %08x\n", r );
2517         VariantClear(&var);
2518
2519         r = IXMLDOMText_get_text(nodetext, &str);
2520         ok(r == S_OK, "ret %08x\n", r );
2521         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2522         SysFreeString(str);
2523
2524         /* ::replaceData() */
2525         V_VT(&var) = VT_BSTR;
2526         V_BSTR(&var) = SysAllocString(szstr1);
2527         r = IXMLDOMText_put_nodeValue(nodetext, var);
2528         ok(r == S_OK, "ret %08x\n", r );
2529         VariantClear(&var);
2530
2531         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2532         ok(r == E_INVALIDARG, "ret %08x\n", r );
2533         r = IXMLDOMText_get_text(nodetext, &str);
2534         ok(r == S_OK, "ret %08x\n", r );
2535         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2536         SysFreeString(str);
2537
2538         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2539         ok(r == S_OK, "ret %08x\n", r );
2540         r = IXMLDOMText_get_text(nodetext, &str);
2541         ok(r == S_OK, "ret %08x\n", r );
2542         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2543         SysFreeString(str);
2544
2545         /* NULL pointer means delete */
2546         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2547         ok(r == S_OK, "ret %08x\n", r );
2548         r = IXMLDOMText_get_text(nodetext, &str);
2549         ok(r == S_OK, "ret %08x\n", r );
2550         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2551         SysFreeString(str);
2552
2553         /* empty string means delete */
2554         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2555         ok(r == S_OK, "ret %08x\n", r );
2556         r = IXMLDOMText_get_text(nodetext, &str);
2557         ok(r == S_OK, "ret %08x\n", r );
2558         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2559         SysFreeString(str);
2560
2561         /* zero count means insert */
2562         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2563         ok(r == S_OK, "ret %08x\n", r );
2564         r = IXMLDOMText_get_text(nodetext, &str);
2565         ok(r == S_OK, "ret %08x\n", r );
2566         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2567         SysFreeString(str);
2568
2569         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2570         ok(r == S_OK, "ret %08x\n", r );
2571
2572         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2573         ok(r == S_OK, "ret %08x\n", r );
2574         r = IXMLDOMText_get_text(nodetext, &str);
2575         ok(r == S_OK, "ret %08x\n", r );
2576         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2577         SysFreeString(str);
2578
2579         /* nonempty string, count greater than its length */
2580         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2581         ok(r == S_OK, "ret %08x\n", r );
2582         r = IXMLDOMText_get_text(nodetext, &str);
2583         ok(r == S_OK, "ret %08x\n", r );
2584         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2585         SysFreeString(str);
2586
2587         /* nonempty string, count less than its length */
2588         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2589         ok(r == S_OK, "ret %08x\n", r );
2590         r = IXMLDOMText_get_text(nodetext, &str);
2591         ok(r == S_OK, "ret %08x\n", r );
2592         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2593         SysFreeString(str);
2594
2595         IXMLDOMText_Release( nodetext );
2596     }
2597
2598     /* test Create Comment */
2599     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2600     ok( r == E_INVALIDARG, "returns %08x\n", r );
2601     node_comment = (IXMLDOMComment*)0x1;
2602
2603     /* empty comment */
2604     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2605     ok( r == S_OK, "returns %08x\n", r );
2606     str = (BSTR)0x1;
2607     r = IXMLDOMComment_get_data(node_comment, &str);
2608     ok( r == S_OK, "returns %08x\n", r );
2609     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2610     IXMLDOMComment_Release(node_comment);
2611     SysFreeString(str);
2612
2613     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2614     ok( r == S_OK, "returns %08x\n", r );
2615     str = (BSTR)0x1;
2616     r = IXMLDOMComment_get_data(node_comment, &str);
2617     ok( r == S_OK, "returns %08x\n", r );
2618     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2619     IXMLDOMComment_Release(node_comment);
2620     SysFreeString(str);
2621
2622     str = SysAllocString(szComment);
2623     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2624     SysFreeString(str);
2625     ok( r == S_OK, "returns %08x\n", r );
2626     if(node_comment)
2627     {
2628         /* Last Child Checks */
2629         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2630         ok(r == E_INVALIDARG, "ret %08x\n", r );
2631
2632         nodeChild = (IXMLDOMNode*)0x1;
2633         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2634         ok(r == S_FALSE, "ret %08x\n", r );
2635         ok(nodeChild == NULL, "pLastChild not NULL\n");
2636
2637         /* baseName */
2638         str = (BSTR)0xdeadbeef;
2639         IXMLDOMComment_get_baseName(node_comment, &str);
2640         ok(r == S_FALSE, "ret %08x\n", r );
2641         ok(str == NULL, "Expected NULL\n");
2642
2643         IXMLDOMComment_Release( node_comment );
2644     }
2645
2646     /* test Create Attribute */
2647     str = SysAllocString(szAttribute);
2648     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2649     ok( r == E_INVALIDARG, "returns %08x\n", r );
2650     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2651     ok( r == S_OK, "returns %08x\n", r );
2652     IXMLDOMText_Release( node_attr);
2653     SysFreeString(str);
2654
2655     /* test Processing Instruction */
2656     str = SysAllocStringLen(NULL, 0);
2657     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2658     ok( r == E_INVALIDARG, "returns %08x\n", r );
2659     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2660     ok( r == E_FAIL, "returns %08x\n", r );
2661     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2662     ok( r == E_FAIL, "returns %08x\n", r );
2663     SysFreeString(str);
2664
2665     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2666     ok( r == S_OK, "returns %08x\n", r );
2667     if(nodePI)
2668     {
2669         /* Last Child Checks */
2670         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2671         ok(r == E_INVALIDARG, "ret %08x\n", r );
2672
2673         nodeChild = (IXMLDOMNode*)0x1;
2674         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2675         ok(r == S_FALSE, "ret %08x\n", r );
2676         ok(nodeChild == NULL, "nodeChild not NULL\n");
2677
2678         /* test nodeName */
2679         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2680         ok(r == S_OK, "ret %08x\n", r );
2681         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2682         SysFreeString(str);
2683
2684         /* test baseName */
2685         str = (BSTR)0x1;
2686         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2687         ok(r == S_OK, "ret %08x\n", r );
2688         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2689         SysFreeString(str);
2690
2691         /* test Target */
2692         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2693         ok(r == S_OK, "ret %08x\n", r );
2694         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2695         SysFreeString(str);
2696
2697         /* test get_data */
2698         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2699         ok(r == S_OK, "ret %08x\n", r );
2700         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2701         SysFreeString(str);
2702
2703         /* test put_data */
2704         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2705         ok(r == E_FAIL, "ret %08x\n", r );
2706
2707         /* test put_data */
2708         V_VT(&var) = VT_BSTR;
2709         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2710         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2711         ok(r == E_FAIL, "ret %08x\n", r );
2712         VariantClear(&var);
2713
2714         /* test get nodeName */
2715         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2716         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2717         ok(r == S_OK, "ret %08x\n", r );
2718         SysFreeString(str);
2719
2720         IXMLDOMProcessingInstruction_Release(nodePI);
2721     }
2722
2723     ref = IXMLDOMDocument_Release( doc );
2724     ok( ref == 0, "got %d\n", ref);
2725
2726     free_bstrs();
2727 }
2728
2729 static void test_persiststreaminit(void)
2730 {
2731     IXMLDOMDocument *doc;
2732     IPersistStreamInit *streaminit;
2733     HRESULT hr;
2734
2735     doc = create_document(&IID_IXMLDOMDocument);
2736     if (!doc) return;
2737
2738     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2739     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2740
2741     hr = IPersistStreamInit_InitNew(streaminit);
2742     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2743
2744     IXMLDOMDocument_Release(doc);
2745 }
2746
2747 static void test_domnode( void )
2748 {
2749     HRESULT r;
2750     IXMLDOMDocument *doc, *owner = NULL;
2751     IXMLDOMElement *element = NULL;
2752     IXMLDOMNamedNodeMap *map = NULL;
2753     IXMLDOMNode *node = NULL, *next = NULL;
2754     IXMLDOMNodeList *list = NULL;
2755     IXMLDOMAttribute *attr = NULL;
2756     DOMNodeType type = NODE_INVALID;
2757     VARIANT_BOOL b;
2758     BSTR str;
2759     VARIANT var;
2760     LONG count;
2761
2762     doc = create_document(&IID_IXMLDOMDocument);
2763     if (!doc) return;
2764
2765     b = FALSE;
2766     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2767     ok( r == S_OK, "loadXML failed\n");
2768     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2769
2770     EXPECT_CHILDREN(doc);
2771
2772     r = IXMLDOMDocument_get_documentElement( doc, &element );
2773     ok( r == S_OK, "should be a document element\n");
2774     ok( element != NULL, "should be an element\n");
2775
2776     VariantInit(&var);
2777     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2778
2779     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2780     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2781
2782     r = IXMLDOMNode_get_nodeValue( doc, &var );
2783     ok( r == S_FALSE, "nextNode returned wrong code\n");
2784     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2785     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2786
2787     if (element)
2788     {
2789         owner = NULL;
2790         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2791         ok( r == S_OK, "get_ownerDocument return code\n");
2792         ok( owner != doc, "get_ownerDocument return\n");
2793         IXMLDOMDocument_Release(owner);
2794
2795         type = NODE_INVALID;
2796         r = IXMLDOMNode_get_nodeType( element, &type);
2797         ok( r == S_OK, "got %08x\n", r);
2798         ok( type == NODE_ELEMENT, "node not an element\n");
2799
2800         str = NULL;
2801         r = IXMLDOMNode_get_baseName( element, &str );
2802         ok( r == S_OK, "get_baseName returned wrong code\n");
2803         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2804         SysFreeString(str);
2805
2806         /* check if nodename is correct */
2807         r = IXMLDOMElement_get_nodeName( element, NULL );
2808         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2809
2810         /* content doesn't matter here */
2811         str = NULL;
2812         r = IXMLDOMElement_get_nodeName( element, &str );
2813         ok ( r == S_OK, "get_nodeName wrong code\n");
2814         ok ( str != NULL, "str is null\n");
2815         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2816         SysFreeString( str );
2817
2818         str = SysAllocString( nonexistent_fileW );
2819         V_VT(&var) = VT_I4;
2820         V_I4(&var) = 0x1234;
2821         r = IXMLDOMElement_getAttribute( element, str, &var );
2822         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2823         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2824         VariantClear(&var);
2825
2826         str = SysAllocString( szdl );   
2827         V_VT(&var) = VT_I4;
2828         V_I4(&var) = 0x1234;
2829         r = IXMLDOMElement_getAttribute( element, str, &var );
2830         ok( r == S_OK, "getAttribute ret %08x\n", r );
2831         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2832         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2833         VariantClear( &var );
2834
2835         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2836         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2837
2838         r = IXMLDOMElement_getAttribute( element, str, NULL );
2839         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2840
2841         attr = NULL;
2842         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2843         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2844         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2845         if (attr)
2846         {
2847             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2848             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2849
2850             /* attribute doesn't have a parent in msxml interpretation */
2851             node = (IXMLDOMNode*)0xdeadbeef;
2852             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2853             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2854             ok( node == NULL, "Expected NULL, got %p\n", node );
2855
2856             IXMLDOMAttribute_Release(attr);
2857         }
2858
2859         SysFreeString( str );
2860
2861         r = IXMLDOMElement_get_attributes( element, &map );
2862         ok( r == S_OK, "get_attributes returned wrong code\n");
2863         ok( map != NULL, "should be attributes\n");
2864
2865         EXPECT_CHILDREN(element);
2866     }
2867     else
2868         ok( FALSE, "no element\n");
2869
2870     if (map)
2871     {
2872         str = SysAllocString( szdl );
2873         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2874         ok( r == S_OK, "getNamedItem returned wrong code\n");
2875         ok( node != NULL, "should be attributes\n");
2876         IXMLDOMNode_Release(node);
2877         SysFreeString( str );
2878
2879         str = SysAllocString( szdl );
2880         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2881         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2882         SysFreeString( str );
2883
2884         /* something that isn't in complete4A */
2885         str = SysAllocString( szOpen );
2886         node = (IXMLDOMNode *) 1;
2887         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2888         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2889         ok( node == NULL, "getNamedItem should have returned NULL\n");
2890         SysFreeString( str );
2891
2892         /* test indexed access of attributes */
2893         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2894         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2895
2896         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2897         ok ( r == S_OK, "get_length wrong code\n");
2898         ok ( count == 1, "get_length != 1\n");
2899
2900         node = NULL;
2901         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2902         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2903         ok ( node == NULL, "there is no node\n");
2904
2905         node = NULL;
2906         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2907         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2908         ok ( node == NULL, "there is no attribute\n");
2909
2910         node = NULL;
2911         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2912         ok ( r == S_OK, "get_item (0) wrong code\n");
2913         ok ( node != NULL, "should be attribute\n");
2914
2915         r = IXMLDOMNode_get_nodeName( node, NULL );
2916         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2917
2918         /* content doesn't matter here */
2919         str = NULL;
2920         r = IXMLDOMNode_get_nodeName( node, &str );
2921         ok ( r == S_OK, "get_nodeName wrong code\n");
2922         ok ( str != NULL, "str is null\n");
2923         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2924         SysFreeString( str );
2925         IXMLDOMNode_Release( node );
2926
2927         /* test sequential access of attributes */
2928         node = NULL;
2929         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2930         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2931         ok ( node != NULL, "nextNode, should be attribute\n");
2932         IXMLDOMNode_Release( node );
2933
2934         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2935         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2936         ok ( node == NULL, "nextNode, there is no attribute\n");
2937
2938         r = IXMLDOMNamedNodeMap_reset( map );
2939         ok ( r == S_OK, "reset should return S_OK\n");
2940
2941         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2942         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2943         ok ( node != NULL, "nextNode, should be attribute\n");
2944     }
2945     else
2946         ok( FALSE, "no map\n");
2947
2948     if (node)
2949     {
2950         type = NODE_INVALID;
2951         r = IXMLDOMNode_get_nodeType( node, &type);
2952         ok( r == S_OK, "getNamedItem returned wrong code\n");
2953         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2954
2955         str = NULL;
2956         r = IXMLDOMNode_get_baseName( node, NULL );
2957         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2958
2959         str = NULL;
2960         r = IXMLDOMNode_get_baseName( node, &str );
2961         ok( r == S_OK, "get_baseName returned wrong code\n");
2962         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2963         SysFreeString( str );
2964
2965         r = IXMLDOMNode_get_childNodes( node, NULL );
2966         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2967
2968         r = IXMLDOMNode_get_childNodes( node, &list );
2969         ok( r == S_OK, "get_childNodes returned wrong code\n");
2970
2971         if (list)
2972         {
2973             r = IXMLDOMNodeList_nextNode( list, &next );
2974             ok( r == S_OK, "nextNode returned wrong code\n");
2975         }
2976         else
2977             ok( FALSE, "no childlist\n");
2978
2979         if (next)
2980         {
2981             EXPECT_NO_CHILDREN(next);
2982
2983             type = NODE_INVALID;
2984             r = IXMLDOMNode_get_nodeType( next, &type);
2985             ok( r == S_OK, "getNamedItem returned wrong code\n");
2986             ok( type == NODE_TEXT, "node not text\n");
2987
2988             str = (BSTR) 1;
2989             r = IXMLDOMNode_get_baseName( next, &str );
2990             ok( r == S_FALSE, "get_baseName returned wrong code\n");
2991             ok( str == NULL, "basename was wrong\n");
2992             SysFreeString(str);
2993         }
2994         else
2995             ok( FALSE, "no next\n");
2996
2997         if (next)
2998             IXMLDOMNode_Release( next );
2999         next = NULL;
3000         if (list)
3001             IXMLDOMNodeList_Release( list );
3002         list = NULL;
3003         if (node)
3004             IXMLDOMNode_Release( node );
3005     }
3006     else
3007         ok( FALSE, "no node\n");
3008     node = NULL;
3009
3010     if (map)
3011         IXMLDOMNamedNodeMap_Release( map );
3012
3013     /* now traverse the tree from the root element */
3014     if (element)
3015     {
3016         r = IXMLDOMNode_get_childNodes( element, &list );
3017         ok( r == S_OK, "get_childNodes returned wrong code\n");
3018
3019         /* using get_item for child list doesn't advance the position */
3020         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3021         expect_node(node, "E2.E2.D1");
3022         IXMLDOMNode_Release(node);
3023         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3024         expect_node(node, "E1.E2.D1");
3025         IXMLDOMNode_Release(node);
3026         ole_check(IXMLDOMNodeList_reset(list));
3027
3028         IXMLDOMNodeList_AddRef(list);
3029         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3030         ole_check(IXMLDOMNodeList_reset(list));
3031
3032         node = (void*)0xdeadbeef;
3033         str = SysAllocString(szdl);
3034         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3035         SysFreeString(str);
3036         ok( r == S_FALSE, "ret %08x\n", r );
3037         ok( node == NULL, "node %p\n", node );
3038
3039         str = SysAllocString(szbs);
3040         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3041         SysFreeString(str);
3042         ok( r == S_OK, "ret %08x\n", r );
3043         r = IXMLDOMNode_Release( node );
3044         ok( r == 0, "ret %08x\n", r );
3045     }
3046     else
3047         ok( FALSE, "no element\n");
3048
3049     if (list)
3050     {
3051         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3052         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3053
3054         r = IXMLDOMNodeList_get_length(list, NULL);
3055         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3056
3057         r = IXMLDOMNodeList_get_length( list, &count );
3058         ok( r == S_OK, "get_length returns %08x\n", r );
3059         ok( count == 4, "get_length got %d\n", count );
3060
3061         r = IXMLDOMNodeList_nextNode(list, NULL);
3062         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3063
3064         r = IXMLDOMNodeList_nextNode( list, &node );
3065         ok( r == S_OK, "nextNode returned wrong code\n");
3066     }
3067     else
3068         ok( FALSE, "no list\n");
3069
3070     if (node)
3071     {
3072         type = NODE_INVALID;
3073         r = IXMLDOMNode_get_nodeType( node, &type);
3074         ok( r == S_OK, "getNamedItem returned wrong code\n");
3075         ok( type == NODE_ELEMENT, "node not text\n");
3076
3077         r = IXMLDOMNode_hasChildNodes( node, NULL );
3078         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3079
3080         EXPECT_CHILDREN(node);
3081
3082         str = NULL;
3083         r = IXMLDOMNode_get_baseName( node, &str );
3084         ok( r == S_OK, "get_baseName returned wrong code\n");
3085         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3086         SysFreeString(str);
3087     }
3088     else
3089         ok( FALSE, "no node\n");
3090
3091     if (node)
3092         IXMLDOMNode_Release( node );
3093     if (list)
3094         IXMLDOMNodeList_Release( list );
3095     if (element)
3096         IXMLDOMElement_Release( element );
3097
3098     b = FALSE;
3099     str = SysAllocString( szComplete5 );
3100     r = IXMLDOMDocument_loadXML( doc, str, &b );
3101     ok( r == S_OK, "loadXML failed\n");
3102     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3103     SysFreeString( str );
3104
3105     EXPECT_CHILDREN(doc);
3106
3107     r = IXMLDOMDocument_get_documentElement( doc, &element );
3108     ok( r == S_OK, "should be a document element\n");
3109     ok( element != NULL, "should be an element\n");
3110
3111     if (element)
3112     {
3113         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3114         BSTR tag = NULL;
3115
3116         /* check if the tag is correct */
3117         r = IXMLDOMElement_get_tagName( element, &tag );
3118         ok( r == S_OK, "couldn't get tag name\n");
3119         ok( tag != NULL, "tag was null\n");
3120         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3121         SysFreeString( tag );
3122     }
3123
3124     if (element)
3125         IXMLDOMElement_Release( element );
3126     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3127
3128     free_bstrs();
3129 }
3130
3131 typedef struct {
3132     DOMNodeType type;
3133     REFIID iid;
3134 } refcount_test_t;
3135
3136 static const refcount_test_t refcount_test[] = {
3137     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3138     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3139     { NODE_TEXT,                   &IID_IXMLDOMText },
3140     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3141     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3142     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3143     { NODE_COMMENT,                &IID_IXMLDOMComment },
3144     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3145     { NODE_INVALID,                &IID_NULL }
3146 };
3147
3148 static void test_refs(void)
3149 {
3150     IXMLDOMImplementation *impl, *impl2;
3151     IXMLDOMElement *element, *elem2;
3152     IXMLDOMNodeList *node_list = NULL;
3153     IXMLDOMNode *node, *node2, *node3;
3154     const refcount_test_t *ptr;
3155     IXMLDOMDocument *doc;
3156     IUnknown *unk, *unk2;
3157     VARIANT_BOOL b;
3158     HRESULT hr;
3159     LONG ref;
3160
3161     doc = create_document(&IID_IXMLDOMDocument);
3162     if (!doc) return;
3163
3164     ptr = refcount_test;
3165     while (ptr->type != NODE_INVALID)
3166     {
3167         IUnknown *node_typed, *node_typed2;
3168         IDispatchEx *dispex, *dispex2;
3169         IDispatch *disp, *disp2;
3170         VARIANT type;
3171
3172         V_VT(&type) = VT_I1;
3173         V_I1(&type) = ptr->type;
3174
3175         EXPECT_REF(doc, 1);
3176         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3177         EXPECT_HR(hr, S_OK);
3178         EXPECT_REF(doc, 1);
3179         EXPECT_REF(node, 1);
3180
3181         /* try IDispatch and IUnknown from IXMLDOMNode */
3182         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3183         EXPECT_HR(hr, S_OK);
3184         EXPECT_REF(unk, 2);
3185 todo_wine {
3186         EXPECT_REF(node, 1);
3187         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3188 }
3189         EXPECT_REF(unk, 2);
3190         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3191         EXPECT_HR(hr, S_OK);
3192         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3193         EXPECT_REF(unk, 3);
3194         todo_wine EXPECT_REF(disp, 1);
3195
3196         EXPECT_REF(unk, 3);
3197         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3198         EXPECT_HR(hr, S_OK);
3199         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3200         EXPECT_REF(unk, 4);
3201         todo_wine EXPECT_REF(disp2, 1);
3202
3203         IDispatch_Release(disp);
3204         IDispatch_Release(disp2);
3205
3206         /* get IXMLDOMNode from this IUnknown */
3207         EXPECT_REF(unk, 2);
3208         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3209         EXPECT_HR(hr, S_OK);
3210         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3211         EXPECT_REF(unk, 3);
3212         todo_wine EXPECT_REF(node2, 1);
3213
3214         EXPECT_REF(unk, 3);
3215         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3216         EXPECT_HR(hr, S_OK);
3217         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3218         EXPECT_REF(unk, 4);
3219         todo_wine EXPECT_REF(node3, 1);
3220
3221         IXMLDOMNode_Release(node2);
3222         IXMLDOMNode_Release(node3);
3223
3224         /* try IDispatchEx from IUnknown */
3225         EXPECT_REF(unk, 2);
3226         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3227         EXPECT_HR(hr, S_OK);
3228         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3229         EXPECT_REF(unk, 3);
3230         todo_wine EXPECT_REF(dispex, 1);
3231
3232         EXPECT_REF(unk, 3);
3233         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3234         EXPECT_HR(hr, S_OK);
3235         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3236         EXPECT_REF(unk, 4);
3237         todo_wine EXPECT_REF(dispex2, 1);
3238
3239         IDispatch_Release(dispex);
3240         IDispatch_Release(dispex2);
3241
3242         /* try corresponding IXMLDOM* */
3243         EXPECT_REF(unk, 2);
3244         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3245         EXPECT_HR(hr, S_OK);
3246         EXPECT_REF(unk, 3);
3247         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3248         EXPECT_HR(hr, S_OK);
3249         EXPECT_REF(unk, 4);
3250         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3251         IUnknown_Release(node_typed);
3252         IUnknown_Release(node_typed2);
3253
3254         /* try invalid IXMLDOM* */
3255         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3256         EXPECT_HR(hr, E_NOINTERFACE);
3257
3258         IUnknown_Release(unk);
3259
3260         EXPECT_REF(node, 1);
3261         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3262         EXPECT_HR(hr, S_OK);
3263         EXPECT_REF(node, 2);
3264         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3265
3266         EXPECT_REF(node, 2);
3267         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3268         EXPECT_HR(hr, S_OK);
3269         EXPECT_REF(node, 3);
3270 todo_wine {
3271         EXPECT_REF(node_typed, 2);
3272         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3273 }
3274         IUnknown_Release(node_typed);
3275
3276         IXMLDOMNode_Release(node2);
3277         IXMLDOMNode_Release(node);
3278
3279         ptr++;
3280     }
3281
3282     EXPECT_REF(doc, 1);
3283     ref = IXMLDOMDocument_Release(doc);
3284     ok( ref == 0, "ref %d\n", ref);
3285
3286     /* check IUnknown after releasing DOM iface */
3287     doc = create_document(&IID_IXMLDOMDocument);
3288     EXPECT_REF(doc, 1);
3289     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3290     EXPECT_HR(hr, S_OK);
3291 todo_wine {
3292     EXPECT_REF(unk, 3);
3293     EXPECT_REF(doc, 1);
3294 }
3295     IXMLDOMDocument_Release(doc);
3296     EXPECT_REF(unk, 1);
3297     IUnknown_Release(unk);
3298
3299     doc = create_document(&IID_IXMLDOMDocument);
3300     if (!doc) return;
3301
3302     EXPECT_REF(doc, 1);
3303     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3304     EXPECT_HR(hr, S_OK);
3305 todo_wine {
3306     EXPECT_REF(unk, 3);
3307     EXPECT_REF(doc, 1);
3308 }
3309     IUnknown_Release(unk);
3310
3311     /* IXMLDOMImplementation */
3312     EXPECT_REF(doc, 1);
3313     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3314     EXPECT_HR(hr, S_OK);
3315     EXPECT_REF(doc, 1);
3316     EXPECT_REF(impl, 1);
3317     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3318     EXPECT_HR(hr, S_OK);
3319     EXPECT_REF(doc, 1);
3320     EXPECT_REF(impl2, 1);
3321     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3322     IXMLDOMImplementation_Release(impl);
3323     IXMLDOMImplementation_Release(impl2);
3324
3325     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3326     EXPECT_HR(hr, S_OK);
3327     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3328
3329     EXPECT_REF(doc, 1);
3330     IXMLDOMDocument_AddRef( doc );
3331     EXPECT_REF(doc, 2);
3332     IXMLDOMDocument_AddRef( doc );
3333     EXPECT_REF(doc, 3);
3334
3335     IXMLDOMDocument_Release( doc );
3336     IXMLDOMDocument_Release( doc );
3337
3338     EXPECT_REF(doc, 1);
3339     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3340     EXPECT_HR(hr, S_OK);
3341 todo_wine {
3342     EXPECT_REF(unk, 3);
3343     EXPECT_REF(doc, 1);
3344 }
3345     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3346     EXPECT_HR(hr, S_OK);
3347 todo_wine {
3348     EXPECT_REF(doc, 1);
3349     EXPECT_REF(element, 2);
3350 }
3351     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3352     EXPECT_HR(hr, S_OK);
3353
3354 todo_wine {
3355     EXPECT_REF(doc, 1);
3356     EXPECT_REF(element, 2);
3357     EXPECT_REF(elem2, 2);
3358 }
3359     IXMLDOMElement_AddRef(element);
3360     todo_wine EXPECT_REF(element, 3);
3361     IXMLDOMElement_Release(element);
3362
3363     /* get IUnknown from a node doesn't touch node instance refcount */
3364     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3365     EXPECT_HR(hr, S_OK);
3366     EXPECT_REF(element, 2);
3367 todo_wine {
3368     EXPECT_REF(unk, 4);
3369     EXPECT_REF(elem2, 2);
3370 }
3371     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3372     EXPECT_HR(hr, S_OK);
3373 todo_wine {
3374     EXPECT_REF(unk, 5);
3375     EXPECT_REF(unk2, 5);
3376 }
3377     EXPECT_REF(element, 2);
3378     EXPECT_REF(elem2, 2);
3379
3380     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3381
3382     IUnknown_Release(unk);
3383     IUnknown_Release(unk2);
3384
3385     /* IUnknown refcount is not affected by node refcount */
3386     todo_wine EXPECT_REF(unk2, 3);
3387     IXMLDOMElement_AddRef(elem2);
3388     todo_wine EXPECT_REF(unk2, 3);
3389     IXMLDOMElement_Release(elem2);
3390
3391     IXMLDOMElement_Release(elem2);
3392     todo_wine EXPECT_REF(unk2, 2);
3393
3394     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3395     EXPECT_HR(hr, S_OK);
3396
3397     todo_wine EXPECT_REF(element, 2);
3398     EXPECT_REF(node_list, 1);
3399
3400     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3401     EXPECT_HR(hr, S_OK);
3402     EXPECT_REF(node_list, 1);
3403     EXPECT_REF(node, 1);
3404
3405     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3406     EXPECT_HR(hr, S_OK);
3407     EXPECT_REF(node_list, 1);
3408     EXPECT_REF(node2, 1);
3409
3410     ref = IXMLDOMNode_Release( node );
3411     ok( ref == 0, "ref %d\n", ref );
3412     ref = IXMLDOMNode_Release( node2 );
3413     ok( ref == 0, "ref %d\n", ref );
3414
3415     ref = IXMLDOMNodeList_Release( node_list );
3416     ok( ref == 0, "ref %d\n", ref );
3417
3418     ok( node != node2, "node %p node2 %p\n", node, node2 );
3419
3420     ref = IXMLDOMDocument_Release( doc );
3421     todo_wine ok( ref == 0, "ref %d\n", ref );
3422
3423     todo_wine EXPECT_REF(element, 2);
3424
3425     /* IUnknown must be unique however we obtain it */
3426     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3427     EXPECT_HR(hr, S_OK);
3428     EXPECT_REF(element, 2);
3429     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3430     EXPECT_HR(hr, S_OK);
3431     todo_wine EXPECT_REF(element, 2);
3432     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3433     EXPECT_HR(hr, S_OK);
3434     todo_wine EXPECT_REF(element, 2);
3435     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3436     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3437
3438     IUnknown_Release( unk2 );
3439     IUnknown_Release( unk );
3440     IXMLDOMNode_Release( node );
3441     todo_wine EXPECT_REF(element, 2);
3442
3443     IXMLDOMElement_Release( element );
3444
3445     free_bstrs();
3446 }
3447
3448 static void test_create(void)
3449 {
3450     static const WCHAR szOne[] = {'1',0};
3451     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3452     HRESULT r;
3453     VARIANT var;
3454     BSTR str, name;
3455     IXMLDOMDocument *doc;
3456     IXMLDOMElement *element;
3457     IXMLDOMComment *comment;
3458     IXMLDOMText *text;
3459     IXMLDOMCDATASection *cdata;
3460     IXMLDOMNode *root, *node, *child;
3461     IXMLDOMNamedNodeMap *attr_map;
3462     IUnknown *unk;
3463     LONG ref;
3464     LONG num;
3465
3466     doc = create_document(&IID_IXMLDOMDocument);
3467     if (!doc) return;
3468
3469     EXPECT_REF(doc, 1);
3470
3471     /* types not supported for creation */
3472     V_VT(&var) = VT_I1;
3473     V_I1(&var) = NODE_DOCUMENT;
3474     node = (IXMLDOMNode*)0x1;
3475     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3476     ok( r == E_INVALIDARG, "returns %08x\n", r );
3477     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3478
3479     V_VT(&var) = VT_I1;
3480     V_I1(&var) = NODE_DOCUMENT_TYPE;
3481     node = (IXMLDOMNode*)0x1;
3482     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3483     ok( r == E_INVALIDARG, "returns %08x\n", r );
3484     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3485
3486     V_VT(&var) = VT_I1;
3487     V_I1(&var) = NODE_ENTITY;
3488     node = (IXMLDOMNode*)0x1;
3489     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3490     ok( r == E_INVALIDARG, "returns %08x\n", r );
3491     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3492
3493     V_VT(&var) = VT_I1;
3494     V_I1(&var) = NODE_NOTATION;
3495     node = (IXMLDOMNode*)0x1;
3496     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3497     ok( r == E_INVALIDARG, "returns %08x\n", r );
3498     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3499
3500     /* NODE_COMMENT */
3501     V_VT(&var) = VT_I1;
3502     V_I1(&var) = NODE_COMMENT;
3503     node = NULL;
3504     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3505     ok( r == S_OK, "returns %08x\n", r );
3506     ok( node != NULL, "\n");
3507
3508     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3509     ok( r == S_OK, "returns %08x\n", r );
3510     IXMLDOMNode_Release(node);
3511
3512     str = NULL;
3513     r = IXMLDOMComment_get_data(comment, &str);
3514     ok( r == S_OK, "returns %08x\n", r );
3515     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3516     IXMLDOMComment_Release(comment);
3517     SysFreeString(str);
3518
3519     node = (IXMLDOMNode*)0x1;
3520     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3521     ok( r == S_OK, "returns %08x\n", r );
3522
3523     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3524     ok( r == S_OK, "returns %08x\n", r );
3525     IXMLDOMNode_Release(node);
3526
3527     str = NULL;
3528     r = IXMLDOMComment_get_data(comment, &str);
3529     ok( r == S_OK, "returns %08x\n", r );
3530     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3531     IXMLDOMComment_Release(comment);
3532     SysFreeString(str);
3533
3534     node = (IXMLDOMNode*)0x1;
3535     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3536     ok( r == S_OK, "returns %08x\n", r );
3537
3538     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3539     ok( r == S_OK, "returns %08x\n", r );
3540     IXMLDOMNode_Release(node);
3541
3542     str = NULL;
3543     r = IXMLDOMComment_get_data(comment, &str);
3544     ok( r == S_OK, "returns %08x\n", r );
3545     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3546     IXMLDOMComment_Release(comment);
3547     SysFreeString(str);
3548
3549     /* NODE_TEXT */
3550     V_VT(&var) = VT_I1;
3551     V_I1(&var) = NODE_TEXT;
3552     node = NULL;
3553     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3554     ok( r == S_OK, "returns %08x\n", r );
3555     ok( node != NULL, "\n");
3556
3557     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3558     ok( r == S_OK, "returns %08x\n", r );
3559     IXMLDOMNode_Release(node);
3560
3561     str = NULL;
3562     r = IXMLDOMText_get_data(text, &str);
3563     ok( r == S_OK, "returns %08x\n", r );
3564     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3565     IXMLDOMText_Release(text);
3566     SysFreeString(str);
3567
3568     node = (IXMLDOMNode*)0x1;
3569     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3570     ok( r == S_OK, "returns %08x\n", r );
3571
3572     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3573     ok( r == S_OK, "returns %08x\n", r );
3574     IXMLDOMNode_Release(node);
3575
3576     str = NULL;
3577     r = IXMLDOMText_get_data(text, &str);
3578     ok( r == S_OK, "returns %08x\n", r );
3579     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3580     IXMLDOMText_Release(text);
3581     SysFreeString(str);
3582
3583     node = (IXMLDOMNode*)0x1;
3584     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3585     ok( r == S_OK, "returns %08x\n", r );
3586
3587     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3588     ok( r == S_OK, "returns %08x\n", r );
3589     IXMLDOMNode_Release(node);
3590
3591     str = NULL;
3592     r = IXMLDOMText_get_data(text, &str);
3593     ok( r == S_OK, "returns %08x\n", r );
3594     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3595     IXMLDOMText_Release(text);
3596     SysFreeString(str);
3597
3598     /* NODE_CDATA_SECTION */
3599     V_VT(&var) = VT_I1;
3600     V_I1(&var) = NODE_CDATA_SECTION;
3601     node = NULL;
3602     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3603     ok( r == S_OK, "returns %08x\n", r );
3604     ok( node != NULL, "\n");
3605
3606     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3607     ok( r == S_OK, "returns %08x\n", r );
3608     IXMLDOMNode_Release(node);
3609
3610     str = NULL;
3611     r = IXMLDOMCDATASection_get_data(cdata, &str);
3612     ok( r == S_OK, "returns %08x\n", r );
3613     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3614     IXMLDOMCDATASection_Release(cdata);
3615     SysFreeString(str);
3616
3617     node = (IXMLDOMNode*)0x1;
3618     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3619     ok( r == S_OK, "returns %08x\n", r );
3620
3621     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3622     ok( r == S_OK, "returns %08x\n", r );
3623     IXMLDOMNode_Release(node);
3624
3625     str = NULL;
3626     r = IXMLDOMCDATASection_get_data(cdata, &str);
3627     ok( r == S_OK, "returns %08x\n", r );
3628     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3629     IXMLDOMCDATASection_Release(cdata);
3630     SysFreeString(str);
3631
3632     node = (IXMLDOMNode*)0x1;
3633     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3634     ok( r == S_OK, "returns %08x\n", r );
3635
3636     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3637     ok( r == S_OK, "returns %08x\n", r );
3638     IXMLDOMNode_Release(node);
3639
3640     str = NULL;
3641     r = IXMLDOMCDATASection_get_data(cdata, &str);
3642     ok( r == S_OK, "returns %08x\n", r );
3643     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3644     IXMLDOMCDATASection_Release(cdata);
3645     SysFreeString(str);
3646
3647     /* NODE_ATTRIBUTE */
3648     V_VT(&var) = VT_I1;
3649     V_I1(&var) = NODE_ATTRIBUTE;
3650     node = (IXMLDOMNode*)0x1;
3651     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3652     ok( r == E_FAIL, "returns %08x\n", r );
3653     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3654
3655     V_VT(&var) = VT_I1;
3656     V_I1(&var) = NODE_ATTRIBUTE;
3657     node = (IXMLDOMNode*)0x1;
3658     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3659     ok( r == E_FAIL, "returns %08x\n", r );
3660     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3661
3662     V_VT(&var) = VT_I1;
3663     V_I1(&var) = NODE_ATTRIBUTE;
3664     str = SysAllocString( szlc );
3665     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3666     ok( r == S_OK, "returns %08x\n", r );
3667     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3668     SysFreeString(str);
3669
3670     /* a name is required for attribute, try a BSTR with first null wchar */
3671     V_VT(&var) = VT_I1;
3672     V_I1(&var) = NODE_ATTRIBUTE;
3673     str = SysAllocString( szstr1 );
3674     str[0] = 0;
3675     node = (IXMLDOMNode*)0x1;
3676     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3677     ok( r == E_FAIL, "returns %08x\n", r );
3678     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3679     SysFreeString(str);
3680
3681     /* NODE_PROCESSING_INSTRUCTION */
3682     V_VT(&var) = VT_I1;
3683     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3684     node = (IXMLDOMNode*)0x1;
3685     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3686     ok( r == E_FAIL, "returns %08x\n", r );
3687     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3688
3689     V_VT(&var) = VT_I1;
3690     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3691     node = (IXMLDOMNode*)0x1;
3692     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3693     ok( r == E_FAIL, "returns %08x\n", r );
3694     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3695
3696     V_VT(&var) = VT_I1;
3697     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3698     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3699     ok( r == E_INVALIDARG, "returns %08x\n", r );
3700
3701     /* NODE_ENTITY_REFERENCE */
3702     V_VT(&var) = VT_I1;
3703     V_I1(&var) = NODE_ENTITY_REFERENCE;
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_ENTITY_REFERENCE;
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     /* NODE_ELEMENT */
3717     V_VT(&var) = VT_I1;
3718     V_I1(&var) = NODE_ELEMENT;
3719     node = (IXMLDOMNode*)0x1;
3720     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3721     ok( r == E_FAIL, "returns %08x\n", r );
3722     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3723
3724     V_VT(&var) = VT_I1;
3725     V_I1(&var) = NODE_ELEMENT;
3726     node = (IXMLDOMNode*)0x1;
3727     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3728     ok( r == E_FAIL, "returns %08x\n", r );
3729     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3730
3731     V_VT(&var) = VT_I1;
3732     V_I1(&var) = NODE_ELEMENT;
3733     str = SysAllocString( szlc );
3734     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3735     ok( r == S_OK, "returns %08x\n", r );
3736     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3737
3738     V_VT(&var) = VT_I1;
3739     V_I1(&var) = NODE_ELEMENT;
3740     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3741     ok( r == E_INVALIDARG, "returns %08x\n", r );
3742
3743     V_VT(&var) = VT_R4;
3744     V_R4(&var) = NODE_ELEMENT;
3745     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3746     ok( r == S_OK, "returns %08x\n", r );
3747     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3748
3749     V_VT(&var) = VT_BSTR;
3750     V_BSTR(&var) = SysAllocString( szOne );
3751     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3752     ok( r == S_OK, "returns %08x\n", r );
3753     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3754     VariantClear(&var);
3755
3756     V_VT(&var) = VT_BSTR;
3757     V_BSTR(&var) = SysAllocString( szOneGarbage );
3758     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3759     ok( r == E_INVALIDARG, "returns %08x\n", r );
3760     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3761     VariantClear(&var);
3762
3763     V_VT(&var) = VT_I4;
3764     V_I4(&var) = NODE_ELEMENT;
3765     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3766     ok( r == S_OK, "returns %08x\n", r );
3767
3768     EXPECT_REF(doc, 1);
3769     r = IXMLDOMDocument_appendChild( doc, node, &root );
3770     ok( r == S_OK, "returns %08x\n", r );
3771     ok( node == root, "%p %p\n", node, root );
3772     EXPECT_REF(doc, 1);
3773
3774     EXPECT_REF(node, 2);
3775
3776     ref = IXMLDOMNode_Release( node );
3777     ok(ref == 1, "ref %d\n", ref);
3778     SysFreeString( str );
3779
3780     V_VT(&var) = VT_I4;
3781     V_I4(&var) = NODE_ELEMENT;
3782     str = SysAllocString( szbs );
3783     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3784     ok( r == S_OK, "returns %08x\n", r );
3785     SysFreeString( str );
3786
3787     EXPECT_REF(node, 1);
3788
3789     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3790     ok( r == S_OK, "returns %08x\n", r );
3791
3792     EXPECT_REF(unk, 2);
3793
3794     V_VT(&var) = VT_EMPTY;
3795     child = NULL;
3796     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3797     ok( r == S_OK, "returns %08x\n", r );
3798     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3799
3800     todo_wine EXPECT_REF(unk, 4);
3801
3802     IXMLDOMNode_Release( child );
3803     IUnknown_Release( unk );
3804
3805     V_VT(&var) = VT_NULL;
3806     V_DISPATCH(&var) = (IDispatch*)node;
3807     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3808     ok( r == S_OK, "returns %08x\n", r );
3809     ok( node == child, "%p %p\n", node, child );
3810     IXMLDOMNode_Release( child );
3811
3812     V_VT(&var) = VT_NULL;
3813     V_DISPATCH(&var) = (IDispatch*)node;
3814     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3815     ok( r == S_OK, "returns %08x\n", r );
3816     IXMLDOMNode_Release( node );
3817
3818     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3819     ok( r == S_OK, "returns %08x\n", r );
3820
3821     r = IXMLDOMElement_get_attributes( element, &attr_map );
3822     ok( r == S_OK, "returns %08x\n", r );
3823     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3824     ok( r == S_OK, "returns %08x\n", r );
3825     ok( num == 0, "num %d\n", num );
3826     IXMLDOMNamedNodeMap_Release( attr_map );
3827
3828     V_VT(&var) = VT_BSTR;
3829     V_BSTR(&var) = SysAllocString( szstr1 );
3830     name = SysAllocString( szdl );
3831     r = IXMLDOMElement_setAttribute( element, name, var );
3832     ok( r == S_OK, "returns %08x\n", r );
3833     r = IXMLDOMElement_get_attributes( element, &attr_map );
3834     ok( r == S_OK, "returns %08x\n", r );
3835     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3836     ok( r == S_OK, "returns %08x\n", r );
3837     ok( num == 1, "num %d\n", num );
3838     IXMLDOMNamedNodeMap_Release( attr_map );
3839     VariantClear(&var);
3840
3841     V_VT(&var) = VT_BSTR;
3842     V_BSTR(&var) = SysAllocString( szstr2 );
3843     r = IXMLDOMElement_setAttribute( element, name, var );
3844     ok( r == S_OK, "returns %08x\n", r );
3845     r = IXMLDOMElement_get_attributes( element, &attr_map );
3846     ok( r == S_OK, "returns %08x\n", r );
3847     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3848     ok( r == S_OK, "returns %08x\n", r );
3849     ok( num == 1, "num %d\n", num );
3850     IXMLDOMNamedNodeMap_Release( attr_map );
3851     VariantClear(&var);
3852     r = IXMLDOMElement_getAttribute( element, name, &var );
3853     ok( r == S_OK, "returns %08x\n", r );
3854     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3855     VariantClear(&var);
3856     SysFreeString(name);
3857
3858     V_VT(&var) = VT_BSTR;
3859     V_BSTR(&var) = SysAllocString( szstr1 );
3860     name = SysAllocString( szlc );
3861     r = IXMLDOMElement_setAttribute( element, name, var );
3862     ok( r == S_OK, "returns %08x\n", r );
3863     r = IXMLDOMElement_get_attributes( element, &attr_map );
3864     ok( r == S_OK, "returns %08x\n", r );
3865     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3866     ok( r == S_OK, "returns %08x\n", r );
3867     ok( num == 2, "num %d\n", num );
3868     IXMLDOMNamedNodeMap_Release( attr_map );
3869     VariantClear(&var);
3870     SysFreeString(name);
3871
3872     V_VT(&var) = VT_I4;
3873     V_I4(&var) = 10;
3874     name = SysAllocString( szbs );
3875     r = IXMLDOMElement_setAttribute( element, name, var );
3876     ok( r == S_OK, "returns %08x\n", r );
3877     VariantClear(&var);
3878     r = IXMLDOMElement_getAttribute( element, name, &var );
3879     ok( r == S_OK, "returns %08x\n", r );
3880     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3881     VariantClear(&var);
3882     SysFreeString(name);
3883
3884     /* Create an Attribute */
3885     V_VT(&var) = VT_I4;
3886     V_I4(&var) = NODE_ATTRIBUTE;
3887     str = SysAllocString( szAttribute );
3888     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3889     ok( r == S_OK, "returns %08x\n", r );
3890     ok( node != NULL, "node was null\n");
3891     SysFreeString(str);
3892
3893     IXMLDOMElement_Release( element );
3894     IXMLDOMNode_Release( root );
3895     IXMLDOMDocument_Release( doc );
3896 }
3897
3898 static void test_getElementsByTagName(void)
3899 {
3900     IXMLDOMNodeList *node_list;
3901     IXMLDOMDocument *doc;
3902     IXMLDOMElement *elem;
3903     WCHAR buff[100];
3904     VARIANT_BOOL b;
3905     HRESULT r;
3906     LONG len;
3907     BSTR str;
3908
3909     doc = create_document(&IID_IXMLDOMDocument);
3910     if (!doc) return;
3911
3912     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3913     ok( r == S_OK, "loadXML failed\n");
3914     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3915
3916     str = SysAllocString( szstar );
3917
3918     /* null arguments cases */
3919     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3920     ok( r == E_INVALIDARG, "ret %08x\n", r );
3921     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3922     ok( r == E_INVALIDARG, "ret %08x\n", r );
3923
3924     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3925     ok( r == S_OK, "ret %08x\n", r );
3926     r = IXMLDOMNodeList_get_length( node_list, &len );
3927     ok( r == S_OK, "ret %08x\n", r );
3928     ok( len == 6, "len %d\n", len );
3929
3930     IXMLDOMNodeList_Release( node_list );
3931     SysFreeString( str );
3932
3933     /* broken query BSTR */
3934     memcpy(&buff[2], szstar, sizeof(szstar));
3935     /* just a big length */
3936     *(DWORD*)buff = 0xf0f0;
3937     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3938     ok( r == S_OK, "ret %08x\n", r );
3939     r = IXMLDOMNodeList_get_length( node_list, &len );
3940     ok( r == S_OK, "ret %08x\n", r );
3941     ok( len == 6, "len %d\n", len );
3942     IXMLDOMNodeList_Release( node_list );
3943
3944     str = SysAllocString( szbs );
3945     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3946     ok( r == S_OK, "ret %08x\n", r );
3947     r = IXMLDOMNodeList_get_length( node_list, &len );
3948     ok( r == S_OK, "ret %08x\n", r );
3949     ok( len == 1, "len %d\n", len );
3950     IXMLDOMNodeList_Release( node_list );
3951     SysFreeString( str );
3952
3953     str = SysAllocString( szdl );
3954     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3955     ok( r == S_OK, "ret %08x\n", r );
3956     r = IXMLDOMNodeList_get_length( node_list, &len );
3957     ok( r == S_OK, "ret %08x\n", r );
3958     ok( len == 0, "len %d\n", len );
3959     IXMLDOMNodeList_Release( node_list );
3960     SysFreeString( str );
3961
3962     str = SysAllocString( szstr1 );
3963     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3964     ok( r == S_OK, "ret %08x\n", r );
3965     r = IXMLDOMNodeList_get_length( node_list, &len );
3966     ok( r == S_OK, "ret %08x\n", r );
3967     ok( len == 0, "len %d\n", len );
3968     IXMLDOMNodeList_Release( node_list );
3969     SysFreeString( str );
3970
3971     /* test for element */
3972     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3973     ok( r == S_OK, "ret %08x\n", r );
3974
3975     str = SysAllocString( szstar );
3976
3977     /* null arguments cases */
3978     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3979     ok( r == E_INVALIDARG, "ret %08x\n", r );
3980     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3981     ok( r == E_INVALIDARG, "ret %08x\n", r );
3982
3983     r = IXMLDOMElement_getElementsByTagName(elem, 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 == 5, "len %d\n", len );
3988     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3989     SysFreeString( str );
3990
3991     /* broken query BSTR */
3992     memcpy(&buff[2], szstar, sizeof(szstar));
3993     /* just a big length */
3994     *(DWORD*)buff = 0xf0f0;
3995     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3996     ok( r == S_OK, "ret %08x\n", r );
3997     r = IXMLDOMNodeList_get_length( node_list, &len );
3998     ok( r == S_OK, "ret %08x\n", r );
3999     ok( len == 5, "len %d\n", len );
4000     IXMLDOMNodeList_Release( node_list );
4001
4002     IXMLDOMElement_Release(elem);
4003
4004     IXMLDOMDocument_Release( doc );
4005
4006     free_bstrs();
4007 }
4008
4009 static void test_get_text(void)
4010 {
4011     HRESULT r;
4012     BSTR str;
4013     VARIANT_BOOL b;
4014     IXMLDOMDocument *doc;
4015     IXMLDOMNode *node, *node2, *node3;
4016     IXMLDOMNode *nodeRoot;
4017     IXMLDOMNodeList *node_list;
4018     IXMLDOMNamedNodeMap *node_map;
4019     LONG len;
4020
4021     doc = create_document(&IID_IXMLDOMDocument);
4022     if (!doc) return;
4023
4024     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4025     ok( r == S_OK, "loadXML failed\n");
4026     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4027
4028     str = SysAllocString( szbs );
4029     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
4030     ok( r == S_OK, "ret %08x\n", r );
4031     SysFreeString(str);
4032
4033     /* Test to get all child node text. */
4034     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
4035     ok( r == S_OK, "ret %08x\n", r );
4036     if(r == S_OK)
4037     {
4038         r = IXMLDOMNode_get_text( nodeRoot, &str );
4039         ok( r == S_OK, "ret %08x\n", r );
4040         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
4041         SysFreeString(str);
4042
4043         IXMLDOMNode_Release(nodeRoot);
4044     }
4045
4046     r = IXMLDOMNodeList_get_length( node_list, NULL );
4047     ok( r == E_INVALIDARG, "ret %08x\n", r );
4048
4049     r = IXMLDOMNodeList_get_length( node_list, &len );
4050     ok( r == S_OK, "ret %08x\n", r );
4051     ok( len == 1, "expect 1 got %d\n", len );
4052
4053     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
4054     ok( r == E_INVALIDARG, "ret %08x\n", r );
4055
4056     r = IXMLDOMNodeList_nextNode( node_list, NULL );
4057     ok( r == E_INVALIDARG, "ret %08x\n", r );
4058
4059     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4060     ok( r == S_OK, "ret %08x\n", r );
4061     IXMLDOMNodeList_Release( node_list );
4062
4063     /* Invalid output parameter*/
4064     r = IXMLDOMNode_get_text( node, NULL );
4065     ok( r == E_INVALIDARG, "ret %08x\n", r );
4066
4067     r = IXMLDOMNode_get_text( node, &str );
4068     ok( r == S_OK, "ret %08x\n", r );
4069     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4070     SysFreeString(str);
4071
4072     r = IXMLDOMNode_get_attributes( node, &node_map );
4073     ok( r == S_OK, "ret %08x\n", r );
4074
4075     str = SysAllocString( szvr );
4076     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4077     ok( r == S_OK, "ret %08x\n", r );
4078     SysFreeString(str);
4079
4080     r = IXMLDOMNode_get_text( node2, &str );
4081     ok( r == S_OK, "ret %08x\n", r );
4082     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4083     SysFreeString(str);
4084
4085     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4086     ok( r == S_OK, "ret %08x\n", r );
4087
4088     r = IXMLDOMNode_get_text( node3, &str );
4089     ok( r == S_OK, "ret %08x\n", r );
4090     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4091     SysFreeString(str);
4092
4093
4094     IXMLDOMNode_Release( node3 );
4095     IXMLDOMNode_Release( node2 );
4096     IXMLDOMNamedNodeMap_Release( node_map );
4097     IXMLDOMNode_Release( node );
4098     IXMLDOMDocument_Release( doc );
4099
4100     free_bstrs();
4101 }
4102
4103 static void test_get_childNodes(void)
4104 {
4105     BSTR str;
4106     VARIANT_BOOL b;
4107     IXMLDOMDocument *doc;
4108     IXMLDOMElement *element;
4109     IXMLDOMNode *node, *node2;
4110     IXMLDOMNodeList *node_list, *node_list2;
4111     HRESULT hr;
4112     LONG len;
4113
4114     doc = create_document(&IID_IXMLDOMDocument);
4115     if (!doc) return;
4116
4117     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4118     EXPECT_HR(hr, S_OK);
4119     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4120
4121     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4122     EXPECT_HR(hr, S_OK);
4123
4124     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4125     EXPECT_HR(hr, S_OK);
4126
4127     hr = IXMLDOMNodeList_get_length( node_list, &len );
4128     EXPECT_HR(hr, S_OK);
4129     ok( len == 4, "len %d\n", len);
4130
4131     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4132     EXPECT_HR(hr, S_OK);
4133
4134     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4135     EXPECT_HR(hr, S_OK);
4136
4137     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4138     EXPECT_HR(hr, S_OK);
4139     ok( len == 0, "len %d\n", len);
4140
4141     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4142     EXPECT_HR(hr, S_FALSE);
4143
4144     IXMLDOMNodeList_Release( node_list2 );
4145     IXMLDOMNode_Release( node );
4146     IXMLDOMNodeList_Release( node_list );
4147     IXMLDOMElement_Release( element );
4148
4149     /* test for children of <?xml ..?> node */
4150     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4151     EXPECT_HR(hr, S_OK);
4152
4153     str = NULL;
4154     hr = IXMLDOMNode_get_nodeName(node, &str);
4155     EXPECT_HR(hr, S_OK);
4156     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4157     SysFreeString(str);
4158
4159     /* it returns empty but valid node list */
4160     node_list = (void*)0xdeadbeef;
4161     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4162     EXPECT_HR(hr, S_OK);
4163
4164     len = -1;
4165     hr = IXMLDOMNodeList_get_length(node_list, &len);
4166     EXPECT_HR(hr, S_OK);
4167     ok(len == 0, "got %d\n", len);
4168
4169     IXMLDOMNodeList_Release( node_list );
4170     IXMLDOMNode_Release(node);
4171
4172     IXMLDOMDocument_Release( doc );
4173     free_bstrs();
4174 }
4175
4176 static void test_get_firstChild(void)
4177 {
4178     static WCHAR xmlW[] = {'x','m','l',0};
4179     IXMLDOMDocument *doc;
4180     IXMLDOMNode *node;
4181     VARIANT_BOOL b;
4182     HRESULT r;
4183     BSTR str;
4184
4185     doc = create_document(&IID_IXMLDOMDocument);
4186     if (!doc) return;
4187
4188     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4189     ok( r == S_OK, "loadXML failed\n");
4190     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4191
4192     r = IXMLDOMDocument_get_firstChild( doc, &node );
4193     ok( r == S_OK, "ret %08x\n", r);
4194
4195     r = IXMLDOMNode_get_nodeName( node, &str );
4196     ok( r == S_OK, "ret %08x\n", r);
4197
4198     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4199
4200     SysFreeString(str);
4201     IXMLDOMNode_Release( node );
4202     IXMLDOMDocument_Release( doc );
4203
4204     free_bstrs();
4205 }
4206
4207 static void test_get_lastChild(void)
4208 {
4209     static WCHAR lcW[] = {'l','c',0};
4210     static WCHAR foW[] = {'f','o',0};
4211     IXMLDOMDocument *doc;
4212     IXMLDOMNode *node, *child;
4213     VARIANT_BOOL b;
4214     HRESULT r;
4215     BSTR str;
4216
4217     doc = create_document(&IID_IXMLDOMDocument);
4218     if (!doc) return;
4219
4220     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4221     ok( r == S_OK, "loadXML failed\n");
4222     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4223
4224     r = IXMLDOMDocument_get_lastChild( doc, &node );
4225     ok( r == S_OK, "ret %08x\n", r);
4226
4227     r = IXMLDOMNode_get_nodeName( node, &str );
4228     ok( r == S_OK, "ret %08x\n", r);
4229
4230     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4231     SysFreeString(str);
4232
4233     r = IXMLDOMNode_get_lastChild( node, &child );
4234     ok( r == S_OK, "ret %08x\n", r);
4235
4236     r = IXMLDOMNode_get_nodeName( child, &str );
4237     ok( r == S_OK, "ret %08x\n", r);
4238
4239     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4240     SysFreeString(str);
4241
4242     IXMLDOMNode_Release( child );
4243     IXMLDOMNode_Release( node );
4244     IXMLDOMDocument_Release( doc );
4245
4246     free_bstrs();
4247 }
4248
4249 static void test_removeChild(void)
4250 {
4251     HRESULT r;
4252     VARIANT_BOOL b;
4253     IXMLDOMDocument *doc;
4254     IXMLDOMElement *element, *lc_element;
4255     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4256     IXMLDOMNodeList *root_list, *fo_list;
4257
4258     doc = create_document(&IID_IXMLDOMDocument);
4259     if (!doc) return;
4260
4261     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4262     ok( r == S_OK, "loadXML failed\n");
4263     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4264
4265     r = IXMLDOMDocument_get_documentElement( doc, &element );
4266     ok( r == S_OK, "ret %08x\n", r);
4267     todo_wine EXPECT_REF(element, 2);
4268
4269     r = IXMLDOMElement_get_childNodes( element, &root_list );
4270     ok( r == S_OK, "ret %08x\n", r);
4271     EXPECT_REF(root_list, 1);
4272
4273     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4274     ok( r == S_OK, "ret %08x\n", r);
4275     EXPECT_REF(fo_node, 1);
4276
4277     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4278     ok( r == S_OK, "ret %08x\n", r);
4279     EXPECT_REF(fo_list, 1);
4280
4281     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4282     ok( r == S_OK, "ret %08x\n", r);
4283     EXPECT_REF(ba_node, 1);
4284
4285     /* invalid parameter: NULL ptr */
4286     removed_node = (void*)0xdeadbeef;
4287     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4288     ok( r == E_INVALIDARG, "ret %08x\n", r );
4289     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4290
4291     /* ba_node is a descendant of element, but not a direct child. */
4292     removed_node = (void*)0xdeadbeef;
4293     EXPECT_REF(ba_node, 1);
4294     EXPECT_CHILDREN(fo_node);
4295     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4296     ok( r == E_INVALIDARG, "ret %08x\n", r );
4297     ok( removed_node == NULL, "%p\n", removed_node );
4298     EXPECT_REF(ba_node, 1);
4299     EXPECT_CHILDREN(fo_node);
4300
4301     EXPECT_REF(ba_node, 1);
4302     EXPECT_REF(fo_node, 1);
4303     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4304     ok( r == S_OK, "ret %08x\n", r);
4305     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4306     EXPECT_REF(fo_node, 2);
4307     EXPECT_REF(ba_node, 1);
4308
4309     /* try removing already removed child */
4310     temp_node = (void*)0xdeadbeef;
4311     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4312     ok( r == E_INVALIDARG, "ret %08x\n", r);
4313     ok( temp_node == NULL, "%p\n", temp_node );
4314     IXMLDOMNode_Release( fo_node );
4315
4316     /* the removed node has no parent anymore */
4317     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4318     ok( r == S_FALSE, "ret %08x\n", r);
4319     ok( temp_node == NULL, "%p\n", temp_node );
4320
4321     IXMLDOMNode_Release( removed_node );
4322     IXMLDOMNode_Release( ba_node );
4323     IXMLDOMNodeList_Release( fo_list );
4324
4325     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4326     ok( r == S_OK, "ret %08x\n", r);
4327
4328     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4329     ok( r == S_OK, "ret %08x\n", r);
4330
4331     /* MS quirk: passing wrong interface pointer works, too */
4332     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4333     ok( r == S_OK, "ret %08x\n", r);
4334     IXMLDOMElement_Release( lc_element );
4335
4336     temp_node = (void*)0xdeadbeef;
4337     r = IXMLDOMNode_get_parentNode( lc_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( lc_node );
4342     IXMLDOMNodeList_Release( root_list );
4343     IXMLDOMElement_Release( element );
4344     IXMLDOMDocument_Release( doc );
4345
4346     free_bstrs();
4347 }
4348
4349 static void test_replaceChild(void)
4350 {
4351     HRESULT r;
4352     VARIANT_BOOL b;
4353     IXMLDOMDocument *doc;
4354     IXMLDOMElement *element, *ba_element;
4355     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4356     IXMLDOMNodeList *root_list, *fo_list;
4357     IUnknown * unk1, *unk2;
4358     LONG len;
4359
4360     doc = create_document(&IID_IXMLDOMDocument);
4361     if (!doc) return;
4362
4363     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4364     ok( r == S_OK, "loadXML failed\n");
4365     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4366
4367     r = IXMLDOMDocument_get_documentElement( doc, &element );
4368     ok( r == S_OK, "ret %08x\n", r);
4369
4370     r = IXMLDOMElement_get_childNodes( element, &root_list );
4371     ok( r == S_OK, "ret %08x\n", r);
4372
4373     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4374     ok( r == S_OK, "ret %08x\n", r);
4375
4376     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4377     ok( r == S_OK, "ret %08x\n", r);
4378
4379     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4380     ok( r == S_OK, "ret %08x\n", r);
4381
4382     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4383     ok( r == S_OK, "ret %08x\n", r);
4384
4385     IXMLDOMNodeList_Release( fo_list );
4386
4387     /* invalid parameter: NULL ptr for element to remove */
4388     removed_node = (void*)0xdeadbeef;
4389     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4390     ok( r == E_INVALIDARG, "ret %08x\n", r );
4391     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4392
4393     /* invalid parameter: NULL for replacement element. (Sic!) */
4394     removed_node = (void*)0xdeadbeef;
4395     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4396     ok( r == E_INVALIDARG, "ret %08x\n", r );
4397     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4398
4399     /* invalid parameter: OldNode is not a child */
4400     removed_node = (void*)0xdeadbeef;
4401     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4402     ok( r == E_INVALIDARG, "ret %08x\n", r );
4403     ok( removed_node == NULL, "%p\n", removed_node );
4404     IXMLDOMNode_Release( lc_node );
4405
4406     /* invalid parameter: would create loop */
4407     removed_node = (void*)0xdeadbeef;
4408     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4409     ok( r == E_FAIL, "ret %08x\n", r );
4410     ok( removed_node == NULL, "%p\n", removed_node );
4411
4412     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4413     ok( r == S_OK, "ret %08x\n", r );
4414
4415     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4416     ok( r == S_OK, "ret %08x\n", r );
4417
4418     /* ba_node and temp_node refer to the same node, yet they
4419        are different interface pointers */
4420     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4421     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4422     ok( r == S_OK, "ret %08x\n", r );
4423     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4424     ok( r == S_OK, "ret %08x\n", r );
4425     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4426
4427     IUnknown_Release( unk1 );
4428     IUnknown_Release( unk2 );
4429
4430     /* ba_node should have been removed from below fo_node */
4431     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4432     ok( r == S_OK, "ret %08x\n", r );
4433
4434     /* MS quirk: replaceChild also accepts elements instead of nodes */
4435     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4436     ok( r == S_OK, "ret %08x\n", r );
4437     EXPECT_REF(ba_element, 2);
4438
4439     removed_node = NULL;
4440     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4441     ok( r == S_OK, "ret %08x\n", r );
4442     ok( removed_node != NULL, "got %p\n", removed_node);
4443     EXPECT_REF(ba_element, 3);
4444     IXMLDOMElement_Release( ba_element );
4445
4446     r = IXMLDOMNodeList_get_length( fo_list, &len);
4447     ok( r == S_OK, "ret %08x\n", r );
4448     ok( len == 0, "len %d\n", len);
4449
4450     IXMLDOMNodeList_Release( fo_list );
4451
4452     IXMLDOMNode_Release(ba_node);
4453     IXMLDOMNode_Release(fo_node);
4454     IXMLDOMNode_Release(temp_node);
4455     IXMLDOMNodeList_Release( root_list );
4456     IXMLDOMElement_Release( element );
4457     IXMLDOMDocument_Release( doc );
4458
4459     free_bstrs();
4460 }
4461
4462 static void test_removeNamedItem(void)
4463 {
4464     IXMLDOMDocument *doc;
4465     IXMLDOMElement *element;
4466     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4467     IXMLDOMNodeList *root_list;
4468     IXMLDOMNamedNodeMap * pr_attrs;
4469     VARIANT_BOOL b;
4470     BSTR str;
4471     LONG len;
4472     HRESULT r;
4473
4474     doc = create_document(&IID_IXMLDOMDocument);
4475     if (!doc) return;
4476
4477     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4478     ok( r == S_OK, "loadXML failed\n");
4479     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4480
4481     r = IXMLDOMDocument_get_documentElement( doc, &element );
4482     ok( r == S_OK, "ret %08x\n", r);
4483
4484     r = IXMLDOMElement_get_childNodes( element, &root_list );
4485     ok( r == S_OK, "ret %08x\n", r);
4486
4487     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4488     ok( r == S_OK, "ret %08x\n", r);
4489
4490     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4491     ok( r == S_OK, "ret %08x\n", r);
4492
4493     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4494     ok( r == S_OK, "ret %08x\n", r);
4495     ok( len == 3, "length %d\n", len);
4496
4497     removed_node = (void*)0xdeadbeef;
4498     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4499     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4500     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4501
4502     removed_node = (void*)0xdeadbeef;
4503     str = SysAllocString(szvr);
4504     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4505     ok ( r == S_OK, "ret %08x\n", r);
4506
4507     removed_node2 = (void*)0xdeadbeef;
4508     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4509     ok ( r == S_FALSE, "ret %08x\n", r);
4510     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4511
4512     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4513     ok( r == S_OK, "ret %08x\n", r);
4514     ok( len == 2, "length %d\n", len);
4515
4516     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4517     ok ( r == S_OK, "ret %08x\n", r);
4518     IXMLDOMNode_Release(removed_node);
4519
4520     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4521     ok( r == S_OK, "ret %08x\n", r);
4522     ok( len == 3, "length %d\n", len);
4523
4524     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4525     ok ( r == S_OK, "ret %08x\n", r);
4526
4527     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4528     ok( r == S_OK, "ret %08x\n", r);
4529     ok( len == 2, "length %d\n", len);
4530
4531     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4532     ok ( r == S_FALSE, "ret %08x\n", r);
4533
4534     SysFreeString(str);
4535
4536     IXMLDOMNamedNodeMap_Release( pr_attrs );
4537     IXMLDOMNode_Release( pr_node );
4538     IXMLDOMNodeList_Release( root_list );
4539     IXMLDOMElement_Release( element );
4540     IXMLDOMDocument_Release( doc );
4541
4542     free_bstrs();
4543 }
4544
4545 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4546 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4547                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4548                                     DWORD expected2)
4549 {
4550     DWORD enabled, supported;
4551     HRESULT hr;
4552
4553     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4554     if (result == result2)
4555         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4556     else
4557         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4558            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4559
4560     supported = enabled = 0xCAFECAFE;
4561     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4562     ok(hr == S_OK, "ret %08x\n", hr );
4563     if (expected == expected2)
4564         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4565     else
4566         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4567            "Expected %08x, got %08x\n", expected2, enabled);
4568
4569     /* reset the safety options */
4570
4571     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4572             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4573             0);
4574     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4575
4576     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4577     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4578     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4579 }
4580
4581 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4582 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4583 {
4584     DWORD enabled = 0, supported = 0;
4585     HRESULT hr;
4586
4587     /* get */
4588     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4589     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4590     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4591     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4592
4593     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4594     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4595     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4596        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4597         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4598              "got %08x\n", supported);
4599     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4600
4601     /* set -- individual flags */
4602
4603     test_IObjectSafety_set(safety, S_OK, S_OK,
4604         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4605         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4606
4607     test_IObjectSafety_set(safety, S_OK, S_OK,
4608         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4609         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4610
4611     test_IObjectSafety_set(safety, S_OK, S_OK,
4612         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4613         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4614
4615     /* set INTERFACE_USES_DISPEX  */
4616
4617     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4618         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4619         0, 0);
4620
4621     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4622         INTERFACE_USES_DISPEX, 0,
4623         0, 0);
4624
4625     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4626         0, INTERFACE_USES_DISPEX,
4627         0, 0);
4628
4629     /* set option masking */
4630
4631     test_IObjectSafety_set(safety, S_OK, S_OK,
4632         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4633         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4634         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4635         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4636
4637     test_IObjectSafety_set(safety, S_OK, S_OK,
4638         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4639         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4640         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4641         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4642
4643     test_IObjectSafety_set(safety, S_OK, S_OK,
4644         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4645         INTERFACE_USES_SECURITY_MANAGER,
4646         0,
4647         0);
4648
4649     /* set -- inheriting previous settings */
4650
4651     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4652                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4653                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4654     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4655     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4656     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4657     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4658     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4659        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4660         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4661              "got %08x\n", supported);
4662
4663     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4664                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4665                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4666     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4667     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4668     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4669     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4670                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4671                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4672     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4673        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4674         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4675              "got %08x\n", supported);
4676 }
4677
4678 static void test_XMLHTTP(void)
4679 {
4680     static const char bodyA[] = "mode=Test";
4681     static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
4682     static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
4683     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4684     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4685
4686     IXMLHttpRequest *xhr;
4687     IObjectSafety *safety;
4688     IObjectWithSite *obj_site, *obj_site2;
4689     BSTR bstrResponse, str, str1;
4690     VARIANT varbody, varbody_ref;
4691     VARIANT dummy;
4692     VARIANT async;
4693     LONG state, status, bound;
4694     IDispatch *event;
4695     void *ptr;
4696     HRESULT hr;
4697     HGLOBAL g;
4698
4699     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4700         &IID_IXMLHttpRequest, (void**)&xhr);
4701     if (FAILED(hr))
4702     {
4703         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4704         return;
4705     }
4706
4707     VariantInit(&dummy);
4708     V_VT(&dummy) = VT_ERROR;
4709     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4710     VariantInit(&async);
4711     V_VT(&async) = VT_BOOL;
4712     V_BOOL(&async) = VARIANT_FALSE;
4713
4714     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4715     EXPECT_HR(hr, S_OK);
4716
4717     hr = IXMLHttpRequest_abort(xhr);
4718     EXPECT_HR(hr, S_OK);
4719
4720     V_VT(&varbody) = VT_I2;
4721     V_I2(&varbody) = 1;
4722     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4723     EXPECT_HR(hr, E_PENDING);
4724     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4725     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4726
4727     V_VT(&varbody) = VT_I2;
4728     V_I2(&varbody) = 1;
4729     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4730     EXPECT_HR(hr, E_PENDING);
4731     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4732     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4733
4734     /* send before open */
4735     hr = IXMLHttpRequest_send(xhr, dummy);
4736     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4737
4738     /* initial status code */
4739     hr = IXMLHttpRequest_get_status(xhr, NULL);
4740     EXPECT_HR(hr, E_INVALIDARG);
4741
4742     status = 0xdeadbeef;
4743     hr = IXMLHttpRequest_get_status(xhr, &status);
4744     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4745     ok(status == 0xdeadbeef, "got %d\n", status);
4746
4747     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4748     ok(hr == E_FAIL, "got 0x%08x\n", hr);
4749
4750     /* invalid parameters */
4751     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4752     EXPECT_HR(hr, E_INVALIDARG);
4753
4754     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4755     EXPECT_HR(hr, E_INVALIDARG);
4756
4757     hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
4758     EXPECT_HR(hr, E_INVALIDARG);
4759
4760     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4761     EXPECT_HR(hr, E_INVALIDARG);
4762
4763     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4764     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4765
4766     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4767     EXPECT_HR(hr, E_INVALIDARG);
4768
4769     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4770     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4771
4772     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4773     EXPECT_HR(hr, E_INVALIDARG);
4774
4775     state = -1;
4776     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4777     EXPECT_HR(hr, S_OK);
4778     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4779
4780     event = create_dispevent();
4781
4782     EXPECT_REF(event, 1);
4783     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4784     EXPECT_HR(hr, S_OK);
4785     EXPECT_REF(event, 2);
4786
4787     g_unexpectedcall = g_expectedcall = 0;
4788
4789     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4790     EXPECT_HR(hr, S_OK);
4791
4792     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4793     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4794
4795     /* status code after ::open() */
4796     status = 0xdeadbeef;
4797     hr = IXMLHttpRequest_get_status(xhr, &status);
4798     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4799     ok(status == 0xdeadbeef, "got %d\n", status);
4800
4801     state = -1;
4802     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4803     EXPECT_HR(hr, S_OK);
4804     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4805
4806     hr = IXMLHttpRequest_abort(xhr);
4807     EXPECT_HR(hr, S_OK);
4808
4809     state = -1;
4810     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4811     EXPECT_HR(hr, S_OK);
4812     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4813         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4814
4815     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4816     EXPECT_HR(hr, S_OK);
4817
4818     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4819     EXPECT_HR(hr, S_OK);
4820
4821     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4822     EXPECT_HR(hr, E_INVALIDARG);
4823
4824     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4825     EXPECT_HR(hr, E_INVALIDARG);
4826
4827     V_VT(&varbody) = VT_BSTR;
4828     V_BSTR(&varbody) = _bstr_(bodyA);
4829
4830     hr = IXMLHttpRequest_send(xhr, varbody);
4831     if (hr == INET_E_RESOURCE_NOT_FOUND)
4832     {
4833         skip("No connection could be made with crossover.codeweavers.com\n");
4834         IXMLHttpRequest_Release(xhr);
4835         return;
4836     }
4837     EXPECT_HR(hr, S_OK);
4838
4839     /* response headers */
4840     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
4841     EXPECT_HR(hr, E_INVALIDARG);
4842     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
4843     EXPECT_HR(hr, S_OK);
4844     /* status line is stripped already */
4845     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
4846     ok(*str, "got empty headers\n");
4847     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
4848     EXPECT_HR(hr, S_OK);
4849     ok(str1 != str, "got %p\n", str1);
4850     SysFreeString(str1);
4851     SysFreeString(str);
4852
4853     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
4854     EXPECT_HR(hr, E_INVALIDARG);
4855     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
4856     EXPECT_HR(hr, E_INVALIDARG);
4857     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
4858     EXPECT_HR(hr, S_OK);
4859     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
4860     SysFreeString(str);
4861
4862     /* status code after ::send() */
4863     status = 0xdeadbeef;
4864     hr = IXMLHttpRequest_get_status(xhr, &status);
4865     EXPECT_HR(hr, S_OK);
4866     ok(status == 200, "got %d\n", status);
4867
4868     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
4869     EXPECT_HR(hr, E_INVALIDARG);
4870
4871     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4872     EXPECT_HR(hr, S_OK);
4873     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
4874     SysFreeString(str);
4875
4876     /* another ::send() after completed request */
4877     V_VT(&varbody) = VT_BSTR;
4878     V_BSTR(&varbody) = _bstr_(bodyA);
4879
4880     hr = IXMLHttpRequest_send(xhr, varbody);
4881     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4882
4883     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4884     EXPECT_HR(hr, S_OK);
4885     /* the server currently returns "FAILED" because the Content-Type header is
4886      * not what the server expects */
4887     if(hr == S_OK)
4888     {
4889         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4890             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4891         SysFreeString(bstrResponse);
4892     }
4893
4894     /* POST: VT_VARIANT|VT_BYREF body */
4895     V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
4896     V_VARIANTREF(&varbody_ref) = &varbody;
4897     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4898     EXPECT_HR(hr, S_OK);
4899     hr = IXMLHttpRequest_send(xhr, varbody_ref);
4900     EXPECT_HR(hr, S_OK);
4901
4902     /* GET request */
4903     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
4904     EXPECT_HR(hr, S_OK);
4905
4906     V_VT(&varbody) = VT_EMPTY;
4907
4908     hr = IXMLHttpRequest_send(xhr, varbody);
4909     if (hr == INET_E_RESOURCE_NOT_FOUND)
4910     {
4911         skip("No connection could be made with crossover.codeweavers.com\n");
4912         IXMLHttpRequest_Release(xhr);
4913         return;
4914     }
4915     EXPECT_HR(hr, S_OK);
4916
4917     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4918     EXPECT_HR(hr, E_INVALIDARG);
4919
4920     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4921     EXPECT_HR(hr, S_OK);
4922     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4923         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4924     SysFreeString(bstrResponse);
4925
4926     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4927     EXPECT_HR(hr, E_INVALIDARG);
4928
4929     V_VT(&varbody) = VT_EMPTY;
4930     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4931     EXPECT_HR(hr, S_OK);
4932     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4933     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4934
4935     bound = -1;
4936     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4937     EXPECT_HR(hr, S_OK);
4938     ok(bound == 0, "got %d, expected zero bound\n", bound);
4939
4940     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4941     EXPECT_HR(hr, S_OK);
4942     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4943     SafeArrayUnaccessData(V_ARRAY(&varbody));
4944
4945     VariantClear(&varbody);
4946
4947     /* get_responseStream */
4948     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
4949     EXPECT_HR(hr, E_INVALIDARG);
4950
4951     V_VT(&varbody) = VT_EMPTY;
4952     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4953     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
4954     EXPECT_HR(hr, S_OK);
4955     EXPECT_REF(V_UNKNOWN(&varbody), 1);
4956
4957     g = NULL;
4958     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
4959     EXPECT_HR(hr, S_OK);
4960     ok(g != NULL, "got %p\n", g);
4961
4962     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4963     EXPECT_HR(hr, S_OK);
4964     if(hr == S_OK)
4965     {
4966         test_IObjectSafety_common(safety);
4967         IObjectSafety_Release(safety);
4968     }
4969
4970     IDispatch_Release(event);
4971
4972     /* interaction with object site */
4973     EXPECT_REF(xhr, 1);
4974     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4975     EXPECT_HR(hr, S_OK);
4976 todo_wine {
4977     EXPECT_REF(xhr, 1);
4978     EXPECT_REF(obj_site, 1);
4979 }
4980
4981     IObjectWithSite_AddRef(obj_site);
4982 todo_wine {
4983     EXPECT_REF(obj_site, 2);
4984     EXPECT_REF(xhr, 1);
4985 }
4986     IObjectWithSite_Release(obj_site);
4987
4988     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
4989     EXPECT_HR(hr, S_OK);
4990 todo_wine {
4991     EXPECT_REF(xhr, 1);
4992     EXPECT_REF(obj_site, 1);
4993     EXPECT_REF(obj_site2, 1);
4994     ok(obj_site != obj_site2, "expected new instance\n");
4995 }
4996     SET_EXPECT(site_qi_IServiceProvider);
4997     SET_EXPECT(sp_queryservice_SID_SBindHost);
4998     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
4999     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
5000     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
5001     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
5002
5003     /* calls to IHTMLDocument2 */
5004     SET_EXPECT(htmldoc2_get_all);
5005     SET_EXPECT(collection_get_length);
5006     SET_EXPECT(htmldoc2_get_url);
5007
5008     SET_EXPECT(site_qi_IXMLDOMDocument);
5009     SET_EXPECT(site_qi_IOleClientSite);
5010
5011     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
5012     EXPECT_HR(hr, S_OK);
5013
5014     CHECK_CALLED(site_qi_IServiceProvider);
5015 todo_wine
5016     CHECK_CALLED(sp_queryservice_SID_SBindHost);
5017     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5018 todo_wine {
5019     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
5020     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
5021     /* this one isn't very reliable
5022     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
5023
5024     CHECK_CALLED(htmldoc2_get_all);
5025     CHECK_CALLED(collection_get_length);
5026     CHECK_CALLED(htmldoc2_get_url);
5027
5028     CHECK_CALLED(site_qi_IXMLDOMDocument);
5029     CHECK_CALLED(site_qi_IOleClientSite);
5030 }
5031     IObjectWithSite_Release(obj_site);
5032
5033     /* try to set site another time */
5034
5035     /* to be removed once IObjectWithSite is properly separated */
5036     SET_EXPECT(site_qi_IServiceProvider);
5037     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5038
5039     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5040     EXPECT_HR(hr, S_OK);
5041
5042     todo_wine EXPECT_REF(xhr, 1);
5043     IXMLHttpRequest_Release(xhr);
5044
5045     /* still works after request is released */
5046
5047     /* to be removed once IObjectWithSite is properly separated */
5048     SET_EXPECT(site_qi_IServiceProvider);
5049     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5050
5051     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5052     EXPECT_HR(hr, S_OK);
5053     IObjectWithSite_Release(obj_site2);
5054
5055     free_bstrs();
5056 }
5057
5058 static void test_IXMLDOMDocument2(void)
5059 {
5060     static const WCHAR emptyW[] = {0};
5061     IXMLDOMDocument2 *doc2, *dtddoc2;
5062     IXMLDOMDocument *doc;
5063     IXMLDOMParseError* err;
5064     IDispatchEx *dispex;
5065     VARIANT_BOOL b;
5066     VARIANT var;
5067     HRESULT r;
5068     LONG res;
5069
5070     doc = create_document(&IID_IXMLDOMDocument);
5071     if (!doc) return;
5072
5073     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
5074     if (!dtddoc2)
5075     {
5076         IXMLDOMDocument_Release(doc);
5077         return;
5078     }
5079
5080     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
5081     ok( r == S_OK, "ret %08x\n", r );
5082     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
5083
5084     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
5085     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
5086     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5087
5088     err = NULL;
5089     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
5090     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5091     ok(err != NULL, "expected a pointer\n");
5092     if (err)
5093     {
5094         res = 0;
5095         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5096         /* XML_E_NOTWF */
5097         ok(res == E_XML_NOTWF, "got %08x\n", res);
5098         IXMLDOMParseError_Release(err);
5099     }
5100
5101     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
5102     ok( r == S_OK, "loadXML failed\n");
5103     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5104
5105     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
5106     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5107
5108     err = NULL;
5109     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5110     ok(err != NULL, "expected a pointer\n");
5111     if (err)
5112     {
5113         res = 0;
5114         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5115         /* XML_E_NODTD */
5116         ok(res == E_XML_NODTD, "got %08x\n", res);
5117         IXMLDOMParseError_Release(err);
5118     }
5119
5120     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5121     ok( r == S_OK, "ret %08x\n", r );
5122     if(r == S_OK)
5123     {
5124         IDispatchEx_Release(dispex);
5125     }
5126
5127     /* we will check if the variant got cleared */
5128     IXMLDOMDocument2_AddRef(doc2);
5129     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5130
5131     V_VT(&var) = VT_UNKNOWN;
5132     V_UNKNOWN(&var) = (IUnknown *)doc2;
5133
5134     /* invalid calls */
5135     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5136     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5137     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5138
5139     /* valid call */
5140     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5141     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5142     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5143     V_VT(&var) = VT_R4;
5144
5145     /* the variant didn't get cleared*/
5146     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5147
5148     /* setProperty tests */
5149     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5150     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5151     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5152     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5153     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5154     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5155
5156     V_VT(&var) = VT_BSTR;
5157     V_BSTR(&var) = SysAllocString(emptyW);
5158     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5159     ok(r == S_OK, "got 0x%08x\n", r);
5160     VariantClear(&var);
5161
5162     V_VT(&var) = VT_I2;
5163     V_I2(&var) = 0;
5164     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5165     ok(r == E_FAIL, "got 0x%08x\n", r);
5166
5167     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5168     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5169     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5170     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5171
5172     IXMLDOMDocument2_Release( doc2 );
5173     IXMLDOMDocument_Release( doc );
5174
5175     /* DTD validation */
5176     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5177     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5178     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5179     err = NULL;
5180     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5181     ok(err != NULL, "expected pointer\n");
5182     if (err)
5183     {
5184         res = 0;
5185         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5186         ok(res == 0, "got %08x\n", res);
5187         IXMLDOMParseError_Release(err);
5188     }
5189
5190     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5191     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5192     err = NULL;
5193     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5194     ok(err != NULL, "expected pointer\n");
5195     if (err)
5196     {
5197         res = 0;
5198         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5199         /* XML_ELEMENT_UNDECLARED */
5200         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5201         IXMLDOMParseError_Release(err);
5202     }
5203
5204     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5205     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5206     err = NULL;
5207     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5208     ok(err != NULL, "expected pointer\n");
5209     if (err)
5210     {
5211         res = 0;
5212         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5213         /* XML_ELEMENT_ID_NOT_FOUND */
5214         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5215         IXMLDOMParseError_Release(err);
5216     }
5217
5218     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5219     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5220     err = NULL;
5221     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5222     ok(err != NULL, "expected pointer\n");
5223     if (err)
5224     {
5225         res = 0;
5226         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5227         /* XML_EMPTY_NOT_ALLOWED */
5228         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5229         IXMLDOMParseError_Release(err);
5230     }
5231
5232     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5233     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5234     err = NULL;
5235     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5236     ok(err != NULL, "expected pointer\n");
5237     if (err)
5238     {
5239         res = 0;
5240         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5241         /* XML_ROOT_NAME_MISMATCH */
5242         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5243         IXMLDOMParseError_Release(err);
5244     }
5245
5246     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5247     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5248     err = NULL;
5249     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5250     ok(err != NULL, "expected pointer\n");
5251     if (err)
5252     {
5253         res = 0;
5254         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5255         /* XML_INVALID_CONTENT */
5256         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5257         IXMLDOMParseError_Release(err);
5258     }
5259
5260     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5261     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5262     err = NULL;
5263     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5264     ok(err != NULL, "expected pointer\n");
5265     if (err)
5266     {
5267         res = 0;
5268         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5269         /* XML_ATTRIBUTE_NOT_DEFINED */
5270         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5271         IXMLDOMParseError_Release(err);
5272     }
5273
5274     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5275     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5276     err = NULL;
5277     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5278     ok(err != NULL, "expected pointer\n");
5279     if (err)
5280     {
5281         res = 0;
5282         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5283         /* XML_ATTRIBUTE_FIXED */
5284         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5285         IXMLDOMParseError_Release(err);
5286     }
5287
5288     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5289     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5290     err = NULL;
5291     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5292     ok(err != NULL, "expected pointer\n");
5293     if (err)
5294     {
5295         res = 0;
5296         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5297         /* XML_ATTRIBUTE_VALUE */
5298         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5299         IXMLDOMParseError_Release(err);
5300     }
5301
5302     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5303     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5304     err = NULL;
5305     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5306     ok(err != NULL, "expected pointer\n");
5307     if (err)
5308     {
5309         res = 0;
5310         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5311         /* XML_ILLEGAL_TEXT */
5312         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5313         IXMLDOMParseError_Release(err);
5314     }
5315
5316     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5317     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5318     err = NULL;
5319     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5320     ok(err != NULL, "expected pointer\n");
5321     if (err)
5322     {
5323         res = 0;
5324         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5325         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5326         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5327         IXMLDOMParseError_Release(err);
5328     }
5329
5330     IXMLDOMDocument2_Release( dtddoc2 );
5331     free_bstrs();
5332 }
5333
5334 #define helper_ole_check(expr) { \
5335     HRESULT r = expr; \
5336     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5337 }
5338
5339 #define helper_expect_list_and_release(list, expstr) { \
5340     char *str = list_to_string(list); \
5341     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5342     if (list) IXMLDOMNodeList_Release(list); \
5343 }
5344
5345 #define helper_expect_bstr_and_release(bstr, str) { \
5346     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5347        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5348     SysFreeString(bstr); \
5349 }
5350
5351 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5352 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5353 {
5354     IXMLDOMNode *node1, *node2;
5355     IXMLDOMNodeList *list;
5356     BSTR bstr;
5357
5358     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5359     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5360     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5361     helper_ole_check(IXMLDOMNodeList_reset(list));
5362     helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
5363
5364     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5365     helper_expect_list_and_release(list, "T1.E1.E4.E1.E2.D1 E2.E1.E4.E1.E2.D1 E3.E1.E4.E1.E2.D1 T4.E1.E4.E1.E2.D1 E5.E1.E4.E1.E2.D1");
5366     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5367     if (str)
5368     {
5369         helper_expect_bstr_and_release(bstr, str);
5370     }
5371     else
5372     {
5373         helper_expect_bstr_and_release(bstr, "This is a description.");
5374     }
5375     IXMLDOMNode_Release(node1);
5376
5377     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5378     helper_expect_list_and_release(list, "T1.E2.E4.E1.E2.D1 E2.E2.E4.E1.E2.D1 T3.E2.E4.E1.E2.D1 E4.E2.E4.E1.E2.D1 T5.E2.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1 T7.E2.E4.E1.E2.D1");
5379     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5380     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5381     IXMLDOMNode_Release(node2);
5382 }
5383
5384 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5385 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5386 {
5387     IXMLDOMNode *node1, *node2;
5388     IXMLDOMNodeList *list;
5389     BSTR bstr;
5390
5391     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5392     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5393     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5394     helper_ole_check(IXMLDOMNodeList_reset(list));
5395     helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
5396
5397     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5398     helper_expect_list_and_release(list, "T1.E2.E8.E2.E2.D1 E2.E2.E8.E2.E2.D1 T3.E2.E8.E2.E2.D1 E4.E2.E8.E2.E2.D1 T5.E2.E8.E2.E2.D1 E6.E2.E8.E2.E2.D1 T7.E2.E8.E2.E2.D1");
5399     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5400     if (str)
5401     {
5402         helper_expect_bstr_and_release(bstr, str);
5403     }
5404     else
5405     {
5406         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5407     }
5408     IXMLDOMNode_Release(node1);
5409
5410     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5411     helper_expect_list_and_release(list, "T1.E4.E8.E2.E2.D1 E2.E4.E8.E2.E2.D1 T3.E4.E8.E2.E2.D1 E4.E4.E8.E2.E2.D1 T5.E4.E8.E2.E2.D1 E6.E4.E8.E2.E2.D1 T7.E4.E8.E2.E2.D1");
5412     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5413     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5414     IXMLDOMNode_Release(node2);
5415 }
5416
5417 static void test_whitespace(void)
5418 {
5419     VARIANT_BOOL b;
5420     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5421
5422     doc1 = create_document(&IID_IXMLDOMDocument2);
5423     doc2 = create_document(&IID_IXMLDOMDocument2);
5424     if (!doc1 || !doc2) return;
5425
5426     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5427     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5428     ok(b == VARIANT_FALSE, "expected false\n");
5429     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5430     ok(b == VARIANT_TRUE, "expected true\n");
5431
5432     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5433     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5434     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5435     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5436
5437     /* switch to XPath */
5438     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5439     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5440
5441     check_ws_ignored(doc1, NULL);
5442     check_ws_preserved(doc2, NULL);
5443
5444     /* new instances copy the property */
5445     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5446     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5447
5448     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5449     ok(b == VARIANT_FALSE, "expected false\n");
5450     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5451     ok(b == VARIANT_TRUE, "expected true\n");
5452
5453     check_ws_ignored(doc3, NULL);
5454     check_ws_preserved(doc4, NULL);
5455
5456     /* setting after loading xml affects trimming of leading/trailing ws only */
5457     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5458     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5459
5460     /* the trailing "\n            " isn't there, because it was ws-only node */
5461     check_ws_ignored(doc1, "\n                This is a description. ");
5462     check_ws_preserved(doc2, "This is a description.");
5463
5464     /* it takes effect on reload */
5465     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5466     ok(b == VARIANT_TRUE, "expected true\n");
5467     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5468     ok(b == VARIANT_FALSE, "expected false\n");
5469
5470     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5471     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5472     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5473     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5474
5475     check_ws_preserved(doc1, NULL);
5476     check_ws_ignored(doc2, NULL);
5477
5478     /* other instances follow suit */
5479     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5480     ok(b == VARIANT_TRUE, "expected true\n");
5481     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5482     ok(b == VARIANT_FALSE, "expected false\n");
5483
5484     check_ws_preserved(doc3, NULL);
5485     check_ws_ignored(doc4, NULL);
5486
5487     IXMLDOMDocument_Release(doc1);
5488     IXMLDOMDocument_Release(doc2);
5489     IXMLDOMDocument_Release(doc3);
5490     IXMLDOMDocument_Release(doc4);
5491     free_bstrs();
5492 }
5493
5494 typedef struct {
5495     const GUID *clsid;
5496     const char *name;
5497     const char *ns;
5498     HRESULT hr;
5499 } selection_ns_t;
5500
5501 /* supposed to be tested with szExampleXML */
5502 static const selection_ns_t selection_ns_data[] = {
5503     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5504     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5505     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5506
5507     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5508     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5509     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5510
5511     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5512     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5513     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5514
5515     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5516     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5517     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5518
5519     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5520     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5521     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5522
5523     { NULL }
5524 };
5525
5526 static void test_XPath(void)
5527 {
5528     const selection_ns_t *ptr = selection_ns_data;
5529     VARIANT var;
5530     VARIANT_BOOL b;
5531     IXMLDOMDocument2 *doc;
5532     IXMLDOMDocument *doc2;
5533     IXMLDOMNode *rootNode;
5534     IXMLDOMNode *elem1Node;
5535     IXMLDOMNode *node;
5536     IXMLDOMNodeList *list;
5537     IXMLDOMElement *elem;
5538     IXMLDOMAttribute *attr;
5539     DOMNodeType type;
5540     HRESULT hr;
5541     LONG len;
5542     BSTR str;
5543
5544     doc = create_document(&IID_IXMLDOMDocument2);
5545     if (!doc) return;
5546
5547     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5548     EXPECT_HR(hr, S_OK);
5549     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5550
5551     /* switch to XPath */
5552     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5553
5554     /* some simple queries*/
5555     EXPECT_REF(doc, 1);
5556     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5557     EXPECT_HR(hr, S_OK);
5558     EXPECT_REF(doc, 1);
5559     EXPECT_LIST_LEN(list, 1);
5560
5561     EXPECT_REF(list, 1);
5562     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5563     EXPECT_HR(hr, S_OK);
5564     EXPECT_REF(list, 1);
5565     EXPECT_REF(rootNode, 1);
5566
5567     hr = IXMLDOMNodeList_reset(list);
5568     EXPECT_HR(hr, S_OK);
5569     expect_list_and_release(list, "E2.D1");
5570
5571 if (0)
5572 {
5573     /* namespace:: axis test is disabled until namespace definitions
5574        are supported as attribute nodes, currently it's another node type */
5575     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5576     EXPECT_HR(hr, S_OK);
5577     len = -1;
5578     hr = IXMLDOMNodeList_get_length(list, &len);
5579     EXPECT_HR(hr, S_OK);
5580     ok(len == 2, "got %d\n", len);
5581
5582     hr = IXMLDOMNodeList_nextNode(list, &node);
5583     EXPECT_HR(hr, S_OK);
5584     type = NODE_INVALID;
5585     hr = IXMLDOMNode_get_nodeType(node, &type);
5586     EXPECT_HR(hr, S_OK);
5587     ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5588     IXMLDOMNode_Release(node);
5589
5590     IXMLDOMNodeList_Release(list);
5591 }
5592
5593     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5594     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5595
5596     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5597     expect_list_and_release(list, "E3.E2.E2.D1");
5598
5599     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5600     /* using get_item for query results advances the position */
5601     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5602     expect_node(node, "E2.E2.D1");
5603     IXMLDOMNode_Release(node);
5604     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5605     expect_node(node, "E4.E2.D1");
5606     IXMLDOMNode_Release(node);
5607     ole_check(IXMLDOMNodeList_reset(list));
5608     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5609
5610     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5611     expect_list_and_release(list, "E2.D1");
5612
5613     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5614     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5615     ole_check(IXMLDOMNodeList_reset(list));
5616     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5617
5618     /* select an attribute */
5619     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5620     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5621
5622     /* would evaluate to a number */
5623     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5624     /* would evaluate to a boolean */
5625     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5626     /* would evaluate to a string */
5627     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5628
5629     /* no results */
5630     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5631     expect_list_and_release(list, "");
5632     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5633     expect_list_and_release(list, "");
5634     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5635     expect_list_and_release(list, "");
5636     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5637     expect_list_and_release(list, "");
5638
5639     /* foo undeclared in document node */
5640     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5641     /* undeclared in <root> node */
5642     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5643     /* undeclared in <elem> node */
5644     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5645     /* but this trick can be used */
5646     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5647     expect_list_and_release(list, "E3.E4.E2.D1");
5648
5649     /* it has to be declared in SelectionNamespaces */
5650     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5651         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5652
5653     /* now the namespace can be used */
5654     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5655     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5656     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5657     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5658     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5659     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5660     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5661     expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
5662
5663     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5664     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5665         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5666
5667     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5668
5669     VariantInit(&var);
5670     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5671     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5672     if (V_VT(&var) == VT_BSTR)
5673         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5674
5675     /* extra attributes - same thing*/
5676     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5677         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5678     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5679
5680     IXMLDOMNode_Release(rootNode);
5681     IXMLDOMNode_Release(elem1Node);
5682
5683     /* alter document with already built list */
5684     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5685     EXPECT_HR(hr, S_OK);
5686     EXPECT_LIST_LEN(list, 1);
5687
5688     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5689     EXPECT_HR(hr, S_OK);
5690     EXPECT_REF(rootNode, 1);
5691     EXPECT_REF(doc, 1);
5692
5693     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5694     EXPECT_HR(hr, S_OK);
5695     IXMLDOMNode_Release(rootNode);
5696
5697     EXPECT_LIST_LEN(list, 1);
5698
5699     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5700     EXPECT_HR(hr, S_OK);
5701     EXPECT_REF(rootNode, 1);
5702
5703     IXMLDOMNodeList_Release(list);
5704
5705     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5706     EXPECT_HR(hr, S_OK);
5707     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5708     SysFreeString(str);
5709     IXMLDOMNode_Release(rootNode);
5710
5711     /* alter node from list and get it another time */
5712     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5713     EXPECT_HR(hr, S_OK);
5714     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5715
5716     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5717     EXPECT_HR(hr, S_OK);
5718     EXPECT_LIST_LEN(list, 1);
5719
5720     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5721     EXPECT_HR(hr, S_OK);
5722
5723     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5724     EXPECT_HR(hr, S_OK);
5725
5726     V_VT(&var) = VT_I2;
5727     V_I2(&var) = 1;
5728     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5729     EXPECT_HR(hr, S_OK);
5730     IXMLDOMElement_Release(elem);
5731     IXMLDOMNode_Release(rootNode);
5732
5733     /* now check attribute to be present */
5734     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5735     EXPECT_HR(hr, S_OK);
5736
5737     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5738     EXPECT_HR(hr, S_OK);
5739
5740     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5741     EXPECT_HR(hr, S_OK);
5742     IXMLDOMAttribute_Release(attr);
5743
5744     IXMLDOMElement_Release(elem);
5745     IXMLDOMNode_Release(rootNode);
5746
5747     /* and now check for attribute in original document */
5748     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5749     EXPECT_HR(hr, S_OK);
5750
5751     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5752     EXPECT_HR(hr, S_OK);
5753     IXMLDOMAttribute_Release(attr);
5754
5755     IXMLDOMElement_Release(elem);
5756
5757     /* attach node from list to another document */
5758     doc2 = create_document(&IID_IXMLDOMDocument);
5759
5760     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5761     EXPECT_HR(hr, S_OK);
5762     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5763
5764     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5765     EXPECT_HR(hr, S_OK);
5766     EXPECT_LIST_LEN(list, 1);
5767
5768     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5769     EXPECT_HR(hr, S_OK);
5770     EXPECT_REF(rootNode, 1);
5771
5772     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5773     EXPECT_HR(hr, S_OK);
5774     EXPECT_REF(rootNode, 1);
5775     EXPECT_REF(doc2, 1);
5776     EXPECT_REF(list, 1);
5777
5778     EXPECT_LIST_LEN(list, 1);
5779
5780     IXMLDOMNode_Release(rootNode);
5781     IXMLDOMNodeList_Release(list);
5782     IXMLDOMDocument_Release(doc2);
5783     IXMLDOMDocument2_Release(doc);
5784
5785     while (ptr->clsid)
5786     {
5787         hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5788         if (hr != S_OK)
5789         {
5790             win_skip("can't create instance of %s\n", ptr->name);
5791             ptr++;
5792             continue;
5793         }
5794
5795         hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5796         EXPECT_HR(hr, S_OK);
5797         ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5798
5799         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5800         EXPECT_HR(hr, S_OK);
5801
5802         V_VT(&var) = VT_BSTR;
5803         V_BSTR(&var) = _bstr_(ptr->ns);
5804
5805         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5806         ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5807
5808         V_VT(&var) = VT_EMPTY;
5809         hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5810         EXPECT_HR(hr, S_OK);
5811         ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5812         ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5813         VariantClear(&var);
5814
5815         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5816         EXPECT_HR(hr, S_OK);
5817         if (hr == S_OK)
5818             expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5819
5820         IXMLDOMDocument2_Release(doc);
5821         ptr++;
5822     }
5823
5824     free_bstrs();
5825 }
5826
5827 static void test_cloneNode(void )
5828 {
5829     IXMLDOMDocument *doc, *doc2;
5830     VARIANT_BOOL b;
5831     IXMLDOMNodeList *pList;
5832     IXMLDOMNamedNodeMap *mapAttr;
5833     LONG length, length1;
5834     LONG attr_cnt, attr_cnt1;
5835     IXMLDOMNode *node;
5836     IXMLDOMNode *node_clone;
5837     IXMLDOMNode *node_first;
5838     HRESULT hr;
5839
5840     doc = create_document(&IID_IXMLDOMDocument);
5841     if (!doc) return;
5842
5843     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5844     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5845
5846     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5847     ok( hr == S_OK, "ret %08x\n", hr );
5848     ok( node != NULL, "node %p\n", node );
5849
5850     /* Check invalid parameter */
5851     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5852     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5853
5854     /* All Children */
5855     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5856     ok( hr == S_OK, "ret %08x\n", hr );
5857     ok( node_clone != NULL, "node %p\n", node );
5858
5859     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5860     ok( hr == S_OK, "ret %08x\n", hr );
5861     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5862     ok( hr == S_OK, "ret %08x\n", hr );
5863     IXMLDOMDocument_Release(doc2);
5864     IXMLDOMNode_Release(node_first);
5865
5866     hr = IXMLDOMNode_get_childNodes(node, &pList);
5867     ok( hr == S_OK, "ret %08x\n", hr );
5868     length = 0;
5869     hr = IXMLDOMNodeList_get_length(pList, &length);
5870     ok( hr == S_OK, "ret %08x\n", hr );
5871     ok(length == 1, "got %d\n", length);
5872     IXMLDOMNodeList_Release(pList);
5873
5874     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5875     ok( hr == S_OK, "ret %08x\n", hr );
5876     attr_cnt = 0;
5877     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5878     ok( hr == S_OK, "ret %08x\n", hr );
5879     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5880     IXMLDOMNamedNodeMap_Release(mapAttr);
5881
5882     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5883     ok( hr == S_OK, "ret %08x\n", hr );
5884     length1 = 0;
5885     hr = IXMLDOMNodeList_get_length(pList, &length1);
5886     ok(length1 == 1, "got %d\n", length1);
5887     ok( hr == S_OK, "ret %08x\n", hr );
5888     IXMLDOMNodeList_Release(pList);
5889
5890     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5891     ok( hr == S_OK, "ret %08x\n", hr );
5892     attr_cnt1 = 0;
5893     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5894     ok( hr == S_OK, "ret %08x\n", hr );
5895     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5896     IXMLDOMNamedNodeMap_Release(mapAttr);
5897
5898     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5899     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5900     IXMLDOMNode_Release(node_clone);
5901
5902     /* No Children */
5903     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5904     ok( hr == S_OK, "ret %08x\n", hr );
5905     ok( node_clone != NULL, "node %p\n", node );
5906
5907     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5908     ok(hr == S_FALSE, "ret %08x\n", hr );
5909
5910     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5911     ok(hr == S_OK, "ret %08x\n", hr );
5912     hr = IXMLDOMNodeList_get_length(pList, &length1);
5913     ok(hr == S_OK, "ret %08x\n", hr );
5914     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5915     IXMLDOMNodeList_Release(pList);
5916
5917     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5918     ok(hr == S_OK, "ret %08x\n", hr );
5919     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5920     ok(hr == S_OK, "ret %08x\n", hr );
5921     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5922     IXMLDOMNamedNodeMap_Release(mapAttr);
5923
5924     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5925     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5926     IXMLDOMNode_Release(node_clone);
5927
5928     IXMLDOMNode_Release(node);
5929     IXMLDOMDocument_Release(doc);
5930     free_bstrs();
5931 }
5932
5933 static void test_xmlTypes(void)
5934 {
5935     IXMLDOMDocument *doc;
5936     IXMLDOMElement *pRoot;
5937     HRESULT hr;
5938     IXMLDOMComment *pComment;
5939     IXMLDOMElement *pElement;
5940     IXMLDOMAttribute *pAttribute;
5941     IXMLDOMNamedNodeMap *pAttribs;
5942     IXMLDOMCDATASection *pCDataSec;
5943     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5944     IXMLDOMDocumentFragment *pDocFrag = NULL;
5945     IXMLDOMEntityReference *pEntityRef = NULL;
5946     BSTR str;
5947     IXMLDOMNode *pNextChild;
5948     VARIANT v;
5949     LONG len = 0;
5950
5951     doc = create_document(&IID_IXMLDOMDocument);
5952     if (!doc) return;
5953
5954     pNextChild = (void*)0xdeadbeef;
5955     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5956     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5957
5958     pNextChild = (void*)0xdeadbeef;
5959     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5960     ok(hr == S_FALSE, "ret %08x\n", hr );
5961     ok(pNextChild == NULL, "pDocChild not NULL\n");
5962
5963     /* test previous Sibling */
5964     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5965     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5966
5967     pNextChild = (void*)0xdeadbeef;
5968     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5969     ok(hr == S_FALSE, "ret %08x\n", hr );
5970     ok(pNextChild == NULL, "pNextChild not NULL\n");
5971
5972     /* test get_dataType */
5973     V_VT(&v) = VT_EMPTY;
5974     hr = IXMLDOMDocument_get_dataType(doc, &v);
5975     ok(hr == S_FALSE, "ret %08x\n", hr );
5976     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5977     VariantClear(&v);
5978
5979     /* test implementation */
5980     hr = IXMLDOMDocument_get_implementation(doc, NULL);
5981     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5982
5983     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5984     ok(hr == S_OK, "ret %08x\n", hr );
5985     if(hr == S_OK)
5986     {
5987         VARIANT_BOOL hasFeature = VARIANT_TRUE;
5988         BSTR sEmpty = SysAllocStringLen(NULL, 0);
5989
5990         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5991         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5992
5993         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5994         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5995
5996         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5997         ok(hr == S_OK, "ret %08x\n", hr );
5998         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5999
6000         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
6001         ok(hr == S_OK, "ret %08x\n", hr );
6002         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
6003
6004         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
6005         ok(hr == S_OK, "ret %08x\n", hr );
6006         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
6007
6008         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6009         ok(hr == S_OK, "ret %08x\n", hr );
6010         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6011
6012         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
6013         ok(hr == S_OK, "ret %08x\n", hr );
6014         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6015
6016         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
6017         ok(hr == S_OK, "ret %08x\n", hr );
6018         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6019
6020         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
6021         ok(hr == S_OK, "ret %08x\n", hr );
6022         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6023
6024         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
6025         ok(hr == S_OK, "ret %08x\n", hr );
6026         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6027
6028         SysFreeString(sEmpty);
6029         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
6030     }
6031
6032     pRoot = (IXMLDOMElement*)0x1;
6033     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
6034     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6035     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6036
6037     pRoot = (IXMLDOMElement*)0x1;
6038     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
6039     ok(hr == E_FAIL, "ret %08x\n", hr );
6040     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6041
6042     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6043     ok(hr == S_OK, "ret %08x\n", hr );
6044     if(hr == S_OK)
6045     {
6046         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6047         ok(hr == S_OK, "ret %08x\n", hr );
6048         if(hr == S_OK)
6049         {
6050             /* Comment */
6051             str = SysAllocString(szComment);
6052             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
6053             SysFreeString(str);
6054             ok(hr == S_OK, "ret %08x\n", hr );
6055             if(hr == S_OK)
6056             {
6057                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
6058                 ok(hr == S_OK, "ret %08x\n", hr );
6059
6060                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
6061                 ok(hr == S_OK, "ret %08x\n", hr );
6062                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
6063                 SysFreeString(str);
6064
6065                 hr = IXMLDOMComment_get_xml(pComment, &str);
6066                 ok(hr == S_OK, "ret %08x\n", hr );
6067                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
6068                 SysFreeString(str);
6069
6070                 /* put data Tests */
6071                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
6072                 ok(hr == S_OK, "ret %08x\n", hr );
6073
6074                 /* get data Tests */
6075                 hr = IXMLDOMComment_get_data(pComment, &str);
6076                 ok(hr == S_OK, "ret %08x\n", hr );
6077                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
6078                 SysFreeString(str);
6079
6080                 /* Confirm XML text is good */
6081                 hr = IXMLDOMComment_get_xml(pComment, &str);
6082                 ok(hr == S_OK, "ret %08x\n", hr );
6083                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
6084                 SysFreeString(str);
6085
6086                 /* Confirm we get the put_data Text back */
6087                 hr = IXMLDOMComment_get_text(pComment, &str);
6088                 ok(hr == S_OK, "ret %08x\n", hr );
6089                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
6090                 SysFreeString(str);
6091
6092                 /* test length property */
6093                 hr = IXMLDOMComment_get_length(pComment, &len);
6094                 ok(hr == S_OK, "ret %08x\n", hr );
6095                 ok(len == 21, "expected 21 got %d\n", len);
6096
6097                 /* test substringData */
6098                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
6099                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6100
6101                 /* test substringData - Invalid offset */
6102                 str = (BSTR)&szElement;
6103                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
6104                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6105                 ok( str == NULL, "incorrect string\n");
6106
6107                 /* test substringData - Invalid offset */
6108                 str = (BSTR)&szElement;
6109                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
6110                 ok(hr == S_FALSE, "ret %08x\n", hr );
6111                 ok( str == NULL, "incorrect string\n");
6112
6113                 /* test substringData - Invalid size */
6114                 str = (BSTR)&szElement;
6115                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
6116                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6117                 ok( str == NULL, "incorrect string\n");
6118
6119                 /* test substringData - Invalid size */
6120                 str = (BSTR)&szElement;
6121                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
6122                 ok(hr == S_FALSE, "ret %08x\n", hr );
6123                 ok( str == NULL, "incorrect string\n");
6124
6125                 /* test substringData - Start of string */
6126                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
6127                 ok(hr == S_OK, "ret %08x\n", hr );
6128                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6129                 SysFreeString(str);
6130
6131                 /* test substringData - Middle of string */
6132                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
6133                 ok(hr == S_OK, "ret %08x\n", hr );
6134                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6135                 SysFreeString(str);
6136
6137                 /* test substringData - End of string */
6138                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
6139                 ok(hr == S_OK, "ret %08x\n", hr );
6140                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6141                 SysFreeString(str);
6142
6143                 /* test appendData */
6144                 hr = IXMLDOMComment_appendData(pComment, NULL);
6145                 ok(hr == S_OK, "ret %08x\n", hr );
6146
6147                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
6148                 ok(hr == S_OK, "ret %08x\n", hr );
6149
6150                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
6151                 ok(hr == S_OK, "ret %08x\n", hr );
6152
6153                 hr = IXMLDOMComment_get_text(pComment, &str);
6154                 ok(hr == S_OK, "ret %08x\n", hr );
6155                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6156                 SysFreeString(str);
6157
6158                 /* test insertData */
6159                 str = SysAllocStringLen(NULL, 0);
6160                 hr = IXMLDOMComment_insertData(pComment, -1, str);
6161                 ok(hr == S_OK, "ret %08x\n", hr );
6162
6163                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
6164                 ok(hr == S_OK, "ret %08x\n", hr );
6165
6166                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
6167                 ok(hr == S_OK, "ret %08x\n", hr );
6168
6169                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
6170                 ok(hr == S_OK, "ret %08x\n", hr );
6171
6172                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
6173                 ok(hr == S_OK, "ret %08x\n", hr );
6174
6175                 hr = IXMLDOMComment_insertData(pComment, 0, str);
6176                 ok(hr == S_OK, "ret %08x\n", hr );
6177                 SysFreeString(str);
6178
6179                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
6180                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6181
6182                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
6183                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6184
6185                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
6186                 ok(hr == S_OK, "ret %08x\n", hr );
6187
6188                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
6189                 ok(hr == S_OK, "ret %08x\n", hr );
6190
6191                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
6192                 ok(hr == S_OK, "ret %08x\n", hr );
6193
6194                 hr = IXMLDOMComment_get_text(pComment, &str);
6195                 ok(hr == S_OK, "ret %08x\n", hr );
6196                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6197                 SysFreeString(str);
6198
6199                 /* delete data */
6200                 /* invalid arguments */
6201                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6202                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6203
6204                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6205                 ok(hr == S_OK, "ret %08x\n", hr );
6206
6207                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6208                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6209
6210                 hr = IXMLDOMComment_get_length(pComment, &len);
6211                 ok(hr == S_OK, "ret %08x\n", hr );
6212                 ok(len == 43, "expected 43 got %d\n", len);
6213
6214                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6215                 ok(hr == S_OK, "ret %08x\n", hr );
6216
6217                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6218                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6219
6220                 /* delete from start */
6221                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6222                 ok(hr == S_OK, "ret %08x\n", hr );
6223
6224                 hr = IXMLDOMComment_get_length(pComment, &len);
6225                 ok(hr == S_OK, "ret %08x\n", hr );
6226                 ok(len == 38, "expected 38 got %d\n", len);
6227
6228                 hr = IXMLDOMComment_get_text(pComment, &str);
6229                 ok(hr == S_OK, "ret %08x\n", hr );
6230                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6231                 SysFreeString(str);
6232
6233                 /* delete from end */
6234                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6235                 ok(hr == S_OK, "ret %08x\n", hr );
6236
6237                 hr = IXMLDOMComment_get_length(pComment, &len);
6238                 ok(hr == S_OK, "ret %08x\n", hr );
6239                 ok(len == 35, "expected 35 got %d\n", len);
6240
6241                 hr = IXMLDOMComment_get_text(pComment, &str);
6242                 ok(hr == S_OK, "ret %08x\n", hr );
6243                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6244                 SysFreeString(str);
6245
6246                 /* delete from inside */
6247                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6248                 ok(hr == S_OK, "ret %08x\n", hr );
6249
6250                 hr = IXMLDOMComment_get_length(pComment, &len);
6251                 ok(hr == S_OK, "ret %08x\n", hr );
6252                 ok(len == 2, "expected 2 got %d\n", len);
6253
6254                 hr = IXMLDOMComment_get_text(pComment, &str);
6255                 ok(hr == S_OK, "ret %08x\n", hr );
6256                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6257                 SysFreeString(str);
6258
6259                 /* delete whole data ... */
6260                 hr = IXMLDOMComment_get_length(pComment, &len);
6261                 ok(hr == S_OK, "ret %08x\n", hr );
6262
6263                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6264                 ok(hr == S_OK, "ret %08x\n", hr );
6265                 /* ... and try again with empty string */
6266                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6267                 ok(hr == S_OK, "ret %08x\n", hr );
6268
6269                 /* ::replaceData() */
6270                 V_VT(&v) = VT_BSTR;
6271                 V_BSTR(&v) = SysAllocString(szstr1);
6272                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6273                 ok(hr == S_OK, "ret %08x\n", hr );
6274                 VariantClear(&v);
6275
6276                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6277                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6278                 hr = IXMLDOMComment_get_text(pComment, &str);
6279                 ok(hr == S_OK, "ret %08x\n", hr );
6280                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6281                 SysFreeString(str);
6282
6283                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6284                 ok(hr == S_OK, "ret %08x\n", hr );
6285                 hr = IXMLDOMComment_get_text(pComment, &str);
6286                 ok(hr == S_OK, "ret %08x\n", hr );
6287                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6288                 SysFreeString(str);
6289
6290                 /* NULL pointer means delete */
6291                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6292                 ok(hr == S_OK, "ret %08x\n", hr );
6293                 hr = IXMLDOMComment_get_text(pComment, &str);
6294                 ok(hr == S_OK, "ret %08x\n", hr );
6295                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6296                 SysFreeString(str);
6297
6298                 /* empty string means delete */
6299                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6300                 ok(hr == S_OK, "ret %08x\n", hr );
6301                 hr = IXMLDOMComment_get_text(pComment, &str);
6302                 ok(hr == S_OK, "ret %08x\n", hr );
6303                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6304                 SysFreeString(str);
6305
6306                 /* zero count means insert */
6307                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6308                 ok(hr == S_OK, "ret %08x\n", hr );
6309                 hr = IXMLDOMComment_get_text(pComment, &str);
6310                 ok(hr == S_OK, "ret %08x\n", hr );
6311                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6312                 SysFreeString(str);
6313
6314                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6315                 ok(hr == S_OK, "ret %08x\n", hr );
6316
6317                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6318                 ok(hr == S_OK, "ret %08x\n", hr );
6319                 hr = IXMLDOMComment_get_text(pComment, &str);
6320                 ok(hr == S_OK, "ret %08x\n", hr );
6321                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6322                 SysFreeString(str);
6323
6324                 /* nonempty string, count greater than its length */
6325                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6326                 ok(hr == S_OK, "ret %08x\n", hr );
6327                 hr = IXMLDOMComment_get_text(pComment, &str);
6328                 ok(hr == S_OK, "ret %08x\n", hr );
6329                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6330                 SysFreeString(str);
6331
6332                 /* nonempty string, count less than its length */
6333                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6334                 ok(hr == S_OK, "ret %08x\n", hr );
6335                 hr = IXMLDOMComment_get_text(pComment, &str);
6336                 ok(hr == S_OK, "ret %08x\n", hr );
6337                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6338                 SysFreeString(str);
6339
6340                 IXMLDOMComment_Release(pComment);
6341             }
6342
6343             /* Element */
6344             str = SysAllocString(szElement);
6345             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6346             SysFreeString(str);
6347             ok(hr == S_OK, "ret %08x\n", hr );
6348             if(hr == S_OK)
6349             {
6350                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6351                 ok(hr == S_OK, "ret %08x\n", hr );
6352
6353                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6354                 ok(hr == S_OK, "ret %08x\n", hr );
6355                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6356                 SysFreeString(str);
6357
6358                 hr = IXMLDOMElement_get_xml(pElement, &str);
6359                 ok(hr == S_OK, "ret %08x\n", hr );
6360                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6361                 SysFreeString(str);
6362
6363                 /* Attribute */
6364                 pAttribute = (IXMLDOMAttribute*)0x1;
6365                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6366                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6367                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6368
6369                 pAttribute = (IXMLDOMAttribute*)0x1;
6370                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6371                 ok(hr == E_FAIL, "ret %08x\n", hr );
6372                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6373
6374                 str = SysAllocString(szAttribute);
6375                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6376                 SysFreeString(str);
6377                 ok(hr == S_OK, "ret %08x\n", hr );
6378                 if(hr == S_OK)
6379                 {
6380                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6381
6382                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6383                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6384
6385                     pNextChild = (IXMLDOMNode *)0x1;
6386                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6387                     ok(hr == S_FALSE, "ret %08x\n", hr );
6388                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6389
6390                     /* test Previous Sibling*/
6391                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6392                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6393
6394                     pNextChild = (IXMLDOMNode *)0x1;
6395                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6396                     ok(hr == S_FALSE, "ret %08x\n", hr );
6397                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6398
6399                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6400                     ok(hr == E_FAIL, "ret %08x\n", hr );
6401                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6402
6403                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6404                     ok(hr == S_OK, "ret %08x\n", hr );
6405                     if ( hr == S_OK )
6406                     {
6407                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6408                         ok(hr == S_OK, "ret %08x\n", hr );
6409
6410                         IXMLDOMNamedNodeMap_Release(pAttribs);
6411                     }
6412
6413                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6414                     ok(hr == S_OK, "ret %08x\n", hr );
6415                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6416                     SysFreeString(str);
6417
6418                     /* test nodeName */
6419                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6420                     ok(hr == S_OK, "ret %08x\n", hr );
6421                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6422                     SysFreeString(str);
6423
6424                     /* test name property */
6425                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6426                     ok(hr == S_OK, "ret %08x\n", hr );
6427                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6428                     SysFreeString(str);
6429
6430                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6431                     ok(hr == S_OK, "ret %08x\n", hr );
6432                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6433                     SysFreeString(str);
6434
6435                     IXMLDOMAttribute_Release(pAttribute);
6436
6437                     /* Check Element again with the Add Attribute*/
6438                     hr = IXMLDOMElement_get_xml(pElement, &str);
6439                     ok(hr == S_OK, "ret %08x\n", hr );
6440                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6441                     SysFreeString(str);
6442                 }
6443
6444                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6445                 ok(hr == S_OK, "ret %08x\n", hr );
6446
6447                 hr = IXMLDOMElement_get_xml(pElement, &str);
6448                 ok(hr == S_OK, "ret %08x\n", hr );
6449                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6450                 SysFreeString(str);
6451
6452                 /* Test for reversible escaping */
6453                 str = SysAllocString( szStrangeChars );
6454                 hr = IXMLDOMElement_put_text(pElement, str);
6455                 ok(hr == S_OK, "ret %08x\n", hr );
6456                 SysFreeString( str );
6457
6458                 hr = IXMLDOMElement_get_xml(pElement, &str);
6459                 ok(hr == S_OK, "ret %08x\n", hr );
6460                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6461                 SysFreeString(str);
6462
6463                 hr = IXMLDOMElement_get_text(pElement, &str);
6464                 ok(hr == S_OK, "ret %08x\n", hr );
6465                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6466                 SysFreeString(str);
6467
6468                 IXMLDOMElement_Release(pElement);
6469             }
6470
6471             /* CData Section */
6472             str = SysAllocString(szCData);
6473             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6474             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6475
6476             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6477             SysFreeString(str);
6478             ok(hr == S_OK, "ret %08x\n", hr );
6479             if(hr == S_OK)
6480             {
6481                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6482                 VARIANT var;
6483
6484                 VariantInit(&var);
6485
6486                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6487                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6488
6489                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6490                 ok(hr == S_OK, "ret %08x\n", hr );
6491
6492                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6493                 ok(hr == S_OK, "ret %08x\n", hr );
6494                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6495                 SysFreeString(str);
6496
6497                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6498                 ok(hr == S_OK, "ret %08x\n", hr );
6499                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6500                 SysFreeString(str);
6501
6502                 /* test lastChild */
6503                 pNextChild = (IXMLDOMNode*)0x1;
6504                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6505                 ok(hr == S_FALSE, "ret %08x\n", hr );
6506                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6507
6508                 /* put data Tests */
6509                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6510                 ok(hr == S_OK, "ret %08x\n", hr );
6511
6512                 /* Confirm XML text is good */
6513                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6514                 ok(hr == S_OK, "ret %08x\n", hr );
6515                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6516                 SysFreeString(str);
6517
6518                 /* Confirm we get the put_data Text back */
6519                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6520                 ok(hr == S_OK, "ret %08x\n", hr );
6521                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6522                 SysFreeString(str);
6523
6524                 /* test length property */
6525                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6526                 ok(hr == S_OK, "ret %08x\n", hr );
6527                 ok(len == 21, "expected 21 got %d\n", len);
6528
6529                 /* test get data */
6530                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6531                 ok(hr == S_OK, "ret %08x\n", hr );
6532                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6533                 SysFreeString(str);
6534
6535                 /* test substringData */
6536                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6537                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6538
6539                 /* test substringData - Invalid offset */
6540                 str = (BSTR)&szElement;
6541                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6542                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6543                 ok( str == NULL, "incorrect string\n");
6544
6545                 /* test substringData - Invalid offset */
6546                 str = (BSTR)&szElement;
6547                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6548                 ok(hr == S_FALSE, "ret %08x\n", hr );
6549                 ok( str == NULL, "incorrect string\n");
6550
6551                 /* test substringData - Invalid size */
6552                 str = (BSTR)&szElement;
6553                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6554                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6555                 ok( str == NULL, "incorrect string\n");
6556
6557                 /* test substringData - Invalid size */
6558                 str = (BSTR)&szElement;
6559                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6560                 ok(hr == S_FALSE, "ret %08x\n", hr );
6561                 ok( str == NULL, "incorrect string\n");
6562
6563                 /* test substringData - Start of string */
6564                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6565                 ok(hr == S_OK, "ret %08x\n", hr );
6566                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6567                 SysFreeString(str);
6568
6569                 /* test substringData - Middle of string */
6570                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6571                 ok(hr == S_OK, "ret %08x\n", hr );
6572                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6573                 SysFreeString(str);
6574
6575                 /* test substringData - End of string */
6576                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6577                 ok(hr == S_OK, "ret %08x\n", hr );
6578                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6579                 SysFreeString(str);
6580
6581                 /* test appendData */
6582                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6583                 ok(hr == S_OK, "ret %08x\n", hr );
6584
6585                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6586                 ok(hr == S_OK, "ret %08x\n", hr );
6587
6588                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6589                 ok(hr == S_OK, "ret %08x\n", hr );
6590
6591                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6592                 ok(hr == S_OK, "ret %08x\n", hr );
6593                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6594                 SysFreeString(str);
6595
6596                 /* test insertData */
6597                 str = SysAllocStringLen(NULL, 0);
6598                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6599                 ok(hr == S_OK, "ret %08x\n", hr );
6600
6601                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6602                 ok(hr == S_OK, "ret %08x\n", hr );
6603
6604                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6605                 ok(hr == S_OK, "ret %08x\n", hr );
6606
6607                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6608                 ok(hr == S_OK, "ret %08x\n", hr );
6609
6610                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6611                 ok(hr == S_OK, "ret %08x\n", hr );
6612
6613                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6614                 ok(hr == S_OK, "ret %08x\n", hr );
6615                 SysFreeString(str);
6616
6617                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6618                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6619
6620                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6621                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6622
6623                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6624                 ok(hr == S_OK, "ret %08x\n", hr );
6625
6626                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6627                 ok(hr == S_OK, "ret %08x\n", hr );
6628
6629                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6630                 ok(hr == S_OK, "ret %08x\n", hr );
6631
6632                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6633                 ok(hr == S_OK, "ret %08x\n", hr );
6634                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6635                 SysFreeString(str);
6636
6637                 /* delete data */
6638                 /* invalid arguments */
6639                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6640                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6641
6642                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6643                 ok(hr == S_OK, "ret %08x\n", hr );
6644
6645                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6646                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6647
6648                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6649                 ok(hr == S_OK, "ret %08x\n", hr );
6650                 ok(len == 43, "expected 43 got %d\n", len);
6651
6652                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6653                 ok(hr == S_OK, "ret %08x\n", hr );
6654
6655                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6656                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6657
6658                 /* delete from start */
6659                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6660                 ok(hr == S_OK, "ret %08x\n", hr );
6661
6662                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6663                 ok(hr == S_OK, "ret %08x\n", hr );
6664                 ok(len == 38, "expected 38 got %d\n", len);
6665
6666                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6667                 ok(hr == S_OK, "ret %08x\n", hr );
6668                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6669                 SysFreeString(str);
6670
6671                 /* delete from end */
6672                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6673                 ok(hr == S_OK, "ret %08x\n", hr );
6674
6675                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6676                 ok(hr == S_OK, "ret %08x\n", hr );
6677                 ok(len == 35, "expected 35 got %d\n", len);
6678
6679                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6680                 ok(hr == S_OK, "ret %08x\n", hr );
6681                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6682                 SysFreeString(str);
6683
6684                 /* delete from inside */
6685                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6686                 ok(hr == S_OK, "ret %08x\n", hr );
6687
6688                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6689                 ok(hr == S_OK, "ret %08x\n", hr );
6690                 ok(len == 2, "expected 2 got %d\n", len);
6691
6692                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6693                 ok(hr == S_OK, "ret %08x\n", hr );
6694                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6695                 SysFreeString(str);
6696
6697                 /* delete whole data ... */
6698                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6699                 ok(hr == S_OK, "ret %08x\n", hr );
6700
6701                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6702                 ok(hr == S_OK, "ret %08x\n", hr );
6703
6704                 /* ... and try again with empty string */
6705                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6706                 ok(hr == S_OK, "ret %08x\n", hr );
6707
6708                 /* ::replaceData() */
6709                 V_VT(&v) = VT_BSTR;
6710                 V_BSTR(&v) = SysAllocString(szstr1);
6711                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6712                 ok(hr == S_OK, "ret %08x\n", hr );
6713                 VariantClear(&v);
6714
6715                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6716                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6717                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6718                 ok(hr == S_OK, "ret %08x\n", hr );
6719                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6720                 SysFreeString(str);
6721
6722                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6723                 ok(hr == S_OK, "ret %08x\n", hr );
6724                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6725                 ok(hr == S_OK, "ret %08x\n", hr );
6726                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6727                 SysFreeString(str);
6728
6729                 /* NULL pointer means delete */
6730                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6731                 ok(hr == S_OK, "ret %08x\n", hr );
6732                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6733                 ok(hr == S_OK, "ret %08x\n", hr );
6734                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6735                 SysFreeString(str);
6736
6737                 /* empty string means delete */
6738                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6739                 ok(hr == S_OK, "ret %08x\n", hr );
6740                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6741                 ok(hr == S_OK, "ret %08x\n", hr );
6742                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6743                 SysFreeString(str);
6744
6745                 /* zero count means insert */
6746                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6747                 ok(hr == S_OK, "ret %08x\n", hr );
6748                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6749                 ok(hr == S_OK, "ret %08x\n", hr );
6750                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6751                 SysFreeString(str);
6752
6753                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6754                 ok(hr == S_OK, "ret %08x\n", hr );
6755
6756                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6757                 ok(hr == S_OK, "ret %08x\n", hr );
6758                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6759                 ok(hr == S_OK, "ret %08x\n", hr );
6760                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6761                 SysFreeString(str);
6762
6763                 /* nonempty string, count greater than its length */
6764                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6765                 ok(hr == S_OK, "ret %08x\n", hr );
6766                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6767                 ok(hr == S_OK, "ret %08x\n", hr );
6768                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6769                 SysFreeString(str);
6770
6771                 /* nonempty string, count less than its length */
6772                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6773                 ok(hr == S_OK, "ret %08x\n", hr );
6774                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6775                 ok(hr == S_OK, "ret %08x\n", hr );
6776                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6777                 SysFreeString(str);
6778
6779                 IXMLDOMCDATASection_Release(pCDataSec);
6780             }
6781
6782             /* Document Fragments */
6783             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6784             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6785
6786             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6787             ok(hr == S_OK, "ret %08x\n", hr );
6788             if(hr == S_OK)
6789             {
6790                 IXMLDOMNode *node;
6791
6792                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6793                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6794
6795                 node = (IXMLDOMNode *)0x1;
6796                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6797                 ok(hr == S_FALSE, "ret %08x\n", hr );
6798                 ok(node == NULL, "expected NULL, got %p\n", node);
6799
6800                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6801                 ok(hr == S_OK, "ret %08x\n", hr );
6802
6803                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6804                 ok(hr == S_OK, "ret %08x\n", hr );
6805                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6806                 SysFreeString(str);
6807
6808                 /* test next Sibling*/
6809                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6810                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6811
6812                 node = (IXMLDOMNode *)0x1;
6813                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6814                 ok(hr == S_FALSE, "ret %08x\n", hr );
6815                 ok(node == NULL, "next sibling not NULL\n");
6816
6817                 /* test Previous Sibling*/
6818                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6819                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6820
6821                 node = (IXMLDOMNode *)0x1;
6822                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6823                 ok(hr == S_FALSE, "ret %08x\n", hr );
6824                 ok(node == NULL, "previous sibling not NULL\n");
6825
6826                 IXMLDOMDocumentFragment_Release(pDocFrag);
6827             }
6828
6829             /* Entity References */
6830             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6831             ok(hr == E_FAIL, "ret %08x\n", hr );
6832             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6833             ok(hr == E_FAIL, "ret %08x\n", hr );
6834
6835             str = SysAllocString(szEntityRef);
6836             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6837             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6838
6839             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6840             SysFreeString(str);
6841             ok(hr == S_OK, "ret %08x\n", hr );
6842             if(hr == S_OK)
6843             {
6844                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6845                 ok(hr == S_OK, "ret %08x\n", hr );
6846
6847                 /* test get_xml*/
6848                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6849                 ok(hr == S_OK, "ret %08x\n", hr );
6850                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6851                 SysFreeString(str);
6852
6853                 IXMLDOMEntityReference_Release(pEntityRef);
6854             }
6855
6856             IXMLDOMElement_Release( pRoot );
6857         }
6858     }
6859
6860     IXMLDOMDocument_Release(doc);
6861
6862     free_bstrs();
6863 }
6864
6865 typedef struct {
6866     const char *name;
6867     const char *type;
6868     HRESULT hr;
6869 } put_datatype_t;
6870
6871 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6872    So many of the names have been changed to reflect this. */
6873 static put_datatype_t put_datatype_data[] = {
6874     { "test_inval",      "abcdefg",     E_FAIL },
6875     { "test_bool",       "Boolean",     S_OK },
6876     { "test_string",     "String",      S_OK },
6877     { "test_number",     "number",      S_OK },
6878     { "test_int",        "InT",         S_OK },
6879     { "test_fixed",      "fixed.14.4",  S_OK },
6880     { "test_datetime",   "DateTime",    S_OK },
6881     { "test_datetimetz", "DateTime.tz", S_OK },
6882     { "test_date",       "Date",        S_OK },
6883     { "test_time",       "Time",        S_OK },
6884     { "test_timetz",     "Time.tz",     S_OK },
6885     { "test_I1",         "I1",          S_OK },
6886     { "test_I2",         "I2",          S_OK },
6887     { "test_I4",         "I4",          S_OK },
6888     { "test_UI1",        "UI1",         S_OK },
6889     { "test_UI2",        "UI2",         S_OK },
6890     { "test_UI4",        "UI4",         S_OK },
6891     { "test_r4",         "r4",          S_OK },
6892     { "test_r8",         "r8",          S_OK },
6893     { "test_float",      "float",       S_OK },
6894     { "test_uuid",       "UuId",        S_OK },
6895     { "test_binhex",     "bin.hex",     S_OK },
6896     { "test_binbase64",  "bin.base64",  S_OK },
6897     { NULL }
6898 };
6899
6900 typedef struct {
6901     DOMNodeType type;
6902     HRESULT hr;
6903 } put_datatype_notype_t;
6904
6905 static put_datatype_notype_t put_dt_notype[] = {
6906     { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6907     { NODE_DOCUMENT_FRAGMENT,      E_FAIL },
6908     { NODE_ENTITY_REFERENCE,       E_FAIL },
6909     { NODE_CDATA_SECTION,          E_FAIL },
6910     { NODE_COMMENT,                E_FAIL },
6911     { NODE_INVALID }
6912 };
6913
6914 static void test_put_dataType( void )
6915 {
6916     const put_datatype_notype_t *ptr2 = put_dt_notype;
6917     const put_datatype_t *ptr = put_datatype_data;
6918     IXMLDOMElement *root, *element;
6919     BSTR nameW, type1W, type2W;
6920     IXMLDOMDocument *doc;
6921     HRESULT hr;
6922
6923     doc = create_document(&IID_IXMLDOMDocument);
6924     if (!doc) return;
6925
6926     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6927     EXPECT_HR(hr, E_INVALIDARG);
6928
6929     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6930     EXPECT_HR(hr, S_OK);
6931
6932     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6933     EXPECT_HR(hr, S_OK);
6934
6935     hr = IXMLDOMElement_put_dataType(root, NULL);
6936     EXPECT_HR(hr, E_INVALIDARG);
6937
6938     while (ptr->name)
6939     {
6940         hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6941         EXPECT_HR(hr, S_OK);
6942         if(hr == S_OK)
6943         {
6944             hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6945             EXPECT_HR(hr, S_OK);
6946
6947             hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6948             ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6949
6950             IXMLDOMElement_Release(element);
6951         }
6952         ptr++;
6953     }
6954
6955     /* check changing types */
6956     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6957     EXPECT_HR(hr, S_OK);
6958
6959     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6960     EXPECT_HR(hr, S_OK);
6961
6962     hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6963     EXPECT_HR(hr, S_OK);
6964
6965     hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6966     EXPECT_HR(hr, S_OK);
6967
6968     IXMLDOMElement_Release(element);
6969
6970     /* try to set type for node without a type */
6971     nameW  = _bstr_("testname");
6972     type1W = _bstr_("string");
6973     type2W = _bstr_("number");
6974     while (ptr2->type != NODE_INVALID)
6975     {
6976         IXMLDOMNode *node;
6977         VARIANT type;
6978
6979         V_VT(&type) = VT_I2;
6980         V_I2(&type) = ptr2->type;
6981
6982         hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
6983         EXPECT_HR(hr, S_OK);
6984         if(hr == S_OK)
6985         {
6986             hr = IXMLDOMElement_appendChild(root, node, NULL);
6987             EXPECT_HR(hr, S_OK);
6988
6989             hr = IXMLDOMNode_put_dataType(node, NULL);
6990             EXPECT_HR(hr, E_INVALIDARG);
6991
6992             hr = IXMLDOMNode_put_dataType(node, type1W);
6993             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6994             hr = IXMLDOMNode_put_dataType(node, type2W);
6995             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6996
6997             IXMLDOMNode_Release(node);
6998         }
6999         ptr2++;
7000     }
7001
7002     IXMLDOMElement_Release(root);
7003     IXMLDOMDocument_Release(doc);
7004     free_bstrs();
7005 }
7006
7007 static void test_save(void)
7008 {
7009     IXMLDOMDocument *doc, *doc2;
7010     IXMLDOMElement *root;
7011     VARIANT file, vDoc;
7012     BSTR sOrig, sNew, filename;
7013     char buffer[100];
7014     DWORD read = 0;
7015     HANDLE hfile;
7016     HRESULT hr;
7017
7018     doc = create_document(&IID_IXMLDOMDocument);
7019     if (!doc) return;
7020
7021     doc2 = create_document(&IID_IXMLDOMDocument);
7022     if (!doc2)
7023     {
7024         IXMLDOMDocument_Release(doc);
7025         return;
7026     }
7027
7028     /* save to IXMLDOMDocument */
7029     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7030     EXPECT_HR(hr, S_OK);
7031
7032     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7033     EXPECT_HR(hr, S_OK);
7034
7035     V_VT(&vDoc) = VT_UNKNOWN;
7036     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
7037
7038     hr = IXMLDOMDocument_save(doc, vDoc);
7039     EXPECT_HR(hr, S_OK);
7040
7041     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7042     EXPECT_HR(hr, S_OK);
7043
7044     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7045     EXPECT_HR(hr, S_OK);
7046
7047     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7048
7049     SysFreeString(sOrig);
7050     SysFreeString(sNew);
7051
7052     IXMLDOMElement_Release(root);
7053     IXMLDOMDocument_Release(doc2);
7054
7055     /* save to path */
7056     V_VT(&file) = VT_BSTR;
7057     V_BSTR(&file) = _bstr_("test.xml");
7058
7059     hr = IXMLDOMDocument_save(doc, file);
7060     EXPECT_HR(hr, S_OK);
7061
7062     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7063     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7064     if(hfile == INVALID_HANDLE_VALUE) return;
7065
7066     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7067     ok(read != 0, "could not read file\n");
7068     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7069
7070     CloseHandle(hfile);
7071     DeleteFile("test.xml");
7072
7073     /* save to path VT_BSTR | VT_BYREF */
7074     filename = _bstr_("test.xml");
7075     V_VT(&file) = VT_BSTR | VT_BYREF;
7076     V_BSTRREF(&file) = &filename;
7077
7078     hr = IXMLDOMDocument_save(doc, file);
7079     EXPECT_HR(hr, S_OK);
7080
7081     IXMLDOMDocument_Release(doc);
7082
7083     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7084     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7085     if(hfile == INVALID_HANDLE_VALUE) return;
7086
7087     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7088     ok(read != 0, "could not read file\n");
7089     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7090
7091     CloseHandle(hfile);
7092     DeleteFile("test.xml");
7093     free_bstrs();
7094 }
7095
7096 static void test_testTransforms(void)
7097 {
7098     IXMLDOMDocument *doc, *docSS;
7099     IXMLDOMNode *pNode;
7100     VARIANT_BOOL bSucc;
7101
7102     HRESULT hr;
7103
7104     doc = create_document(&IID_IXMLDOMDocument);
7105     if (!doc) return;
7106
7107     docSS = create_document(&IID_IXMLDOMDocument);
7108     if (!docSS)
7109     {
7110         IXMLDOMDocument_Release(doc);
7111         return;
7112     }
7113
7114     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7115     ok(hr == S_OK, "ret %08x\n", hr );
7116
7117     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7118     ok(hr == S_OK, "ret %08x\n", hr );
7119
7120     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7121     ok(hr == S_OK, "ret %08x\n", hr );
7122     if(hr == S_OK)
7123     {
7124         BSTR bOut;
7125
7126         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7127         ok(hr == S_OK, "ret %08x\n", hr );
7128         if(hr == S_OK)
7129         {
7130             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7131             SysFreeString(bOut);
7132         }
7133
7134         IXMLDOMNode_Release(pNode);
7135     }
7136
7137     IXMLDOMDocument_Release(docSS);
7138     IXMLDOMDocument_Release(doc);
7139
7140     free_bstrs();
7141 }
7142
7143 static void test_namespaces(void)
7144 {
7145     static const CHAR namespaces_xmlA[] =
7146         "<?xml version=\"1.0\"?>\n"
7147         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7148         "  <XMI.content>"
7149         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7150         "  </XMI.content>"
7151         "</XMI>";
7152
7153     IXMLDOMDocument *doc;
7154     IXMLDOMElement *elem;
7155     IXMLDOMNode *node;
7156
7157     VARIANT_BOOL b;
7158     VARIANT var;
7159     HRESULT hr;
7160     BSTR str;
7161
7162     doc = create_document(&IID_IXMLDOMDocument);
7163     if (!doc) return;
7164
7165     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7166     EXPECT_HR(hr, S_OK);
7167     ok(b == VARIANT_TRUE, "got %d\n", b);
7168
7169     str = (BSTR)0xdeadbeef;
7170     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7171     EXPECT_HR(hr, S_FALSE);
7172     ok(str == NULL, "got %p\n", str);
7173
7174     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7175     EXPECT_HR(hr, S_OK);
7176     if(hr == S_OK)
7177     {
7178         IXMLDOMAttribute *attr;
7179         IXMLDOMNode *node2;
7180
7181         hr = IXMLDOMNode_get_firstChild(node, &node2);
7182         EXPECT_HR(hr, S_OK);
7183         ok(node2 != NULL, "got %p\n", node2);
7184
7185         /* Test get_prefix */
7186         hr = IXMLDOMNode_get_prefix(node2, NULL);
7187         EXPECT_HR(hr, E_INVALIDARG);
7188         /* NOTE: Need to test that arg2 gets cleared on Error. */
7189
7190         hr = IXMLDOMNode_get_prefix(node2, &str);
7191         EXPECT_HR(hr, S_OK);
7192         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7193         SysFreeString(str);
7194
7195         hr = IXMLDOMNode_get_nodeName(node2, &str);
7196         EXPECT_HR(hr, S_OK);
7197         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7198         SysFreeString(str);
7199
7200         /* Test get_namespaceURI */
7201         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7202         EXPECT_HR(hr, E_INVALIDARG);
7203         /* NOTE: Need to test that arg2 gets cleared on Error. */
7204
7205         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7206         EXPECT_HR(hr, S_OK);
7207         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7208         SysFreeString(str);
7209
7210         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7211         EXPECT_HR(hr, S_OK);
7212
7213         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7214         EXPECT_HR(hr, S_OK);
7215
7216         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7217         EXPECT_HR(hr, S_OK);
7218         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7219         SysFreeString(str);
7220
7221         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7222         EXPECT_HR(hr, S_OK);
7223         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7224         SysFreeString(str);
7225
7226         IXMLDOMAttribute_Release(attr);
7227         IXMLDOMElement_Release(elem);
7228
7229         IXMLDOMNode_Release(node2);
7230         IXMLDOMNode_Release(node);
7231     }
7232
7233     IXMLDOMDocument_Release(doc);
7234
7235     /* create on element and try to alter namespace after that */
7236     doc = create_document(&IID_IXMLDOMDocument);
7237     if (!doc) return;
7238
7239     V_VT(&var) = VT_I2;
7240     V_I2(&var) = NODE_ELEMENT;
7241
7242     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7243     EXPECT_HR(hr, S_OK);
7244
7245     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7246     EXPECT_HR(hr, S_OK);
7247
7248     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7249     EXPECT_HR(hr, S_OK);
7250
7251     V_VT(&var) = VT_BSTR;
7252     V_BSTR(&var) = _bstr_("ns/uri2");
7253
7254     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7255     EXPECT_HR(hr, E_INVALIDARG);
7256
7257     V_VT(&var) = VT_BSTR;
7258     V_BSTR(&var) = _bstr_("ns/uri");
7259
7260     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7261     EXPECT_HR(hr, S_OK);
7262
7263     hr = IXMLDOMElement_get_xml(elem, &str);
7264     EXPECT_HR(hr, S_OK);
7265     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7266     SysFreeString(str);
7267
7268     IXMLDOMElement_Release(elem);
7269     IXMLDOMDocument_Release(doc);
7270
7271     /* create on element and try to alter namespace after that */
7272     doc = create_document_version(60, &IID_IXMLDOMDocument);
7273     if (!doc) return;
7274
7275     V_VT(&var) = VT_I2;
7276     V_I2(&var) = NODE_ELEMENT;
7277
7278     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7279     EXPECT_HR(hr, S_OK);
7280
7281     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7282     EXPECT_HR(hr, S_OK);
7283
7284     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7285     EXPECT_HR(hr, S_OK);
7286
7287     /* try same prefix, different uri */
7288     V_VT(&var) = VT_BSTR;
7289     V_BSTR(&var) = _bstr_("ns/uri2");
7290
7291     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7292     EXPECT_HR(hr, E_INVALIDARG);
7293
7294     /* try same prefix and uri */
7295     V_VT(&var) = VT_BSTR;
7296     V_BSTR(&var) = _bstr_("ns/uri");
7297
7298     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7299     EXPECT_HR(hr, S_OK);
7300
7301     hr = IXMLDOMElement_get_xml(elem, &str);
7302     EXPECT_HR(hr, S_OK);
7303     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7304     SysFreeString(str);
7305
7306     IXMLDOMElement_Release(elem);
7307     IXMLDOMDocument_Release(doc);
7308
7309     free_bstrs();
7310 }
7311
7312 static void test_FormattingXML(void)
7313 {
7314     IXMLDOMDocument *doc;
7315     IXMLDOMElement *pElement;
7316     VARIANT_BOOL bSucc;
7317     HRESULT hr;
7318     BSTR str;
7319     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7320     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7321
7322     doc = create_document(&IID_IXMLDOMDocument);
7323     if (!doc) return;
7324
7325     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7326     ok(hr == S_OK, "ret %08x\n", hr );
7327     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7328
7329     if(bSucc == VARIANT_TRUE)
7330     {
7331         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7332         ok(hr == S_OK, "ret %08x\n", hr );
7333         if(hr == S_OK)
7334         {
7335             hr = IXMLDOMElement_get_xml(pElement, &str);
7336             ok(hr == S_OK, "ret %08x\n", hr );
7337             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7338             SysFreeString(str);
7339
7340             IXMLDOMElement_Release(pElement);
7341         }
7342     }
7343
7344     IXMLDOMDocument_Release(doc);
7345
7346     free_bstrs();
7347 }
7348
7349 typedef struct _nodetypedvalue_t {
7350     const char *name;
7351     VARTYPE type;
7352     const char *value; /* value in string format */
7353 } nodetypedvalue_t;
7354
7355 static const nodetypedvalue_t get_nodetypedvalue[] = {
7356     { "root/string",    VT_BSTR, "Wine" },
7357     { "root/string2",   VT_BSTR, "String" },
7358     { "root/number",    VT_BSTR, "12.44" },
7359     { "root/number2",   VT_BSTR, "-3.71e3" },
7360     { "root/int",       VT_I4,   "-13" },
7361     { "root/fixed",     VT_CY,   "7322.9371" },
7362     { "root/bool",      VT_BOOL, "-1" },
7363     { "root/datetime",  VT_DATE, "40135.14" },
7364     { "root/datetimetz",VT_DATE, "37813.59" },
7365     { "root/date",      VT_DATE, "665413" },
7366     { "root/time",      VT_DATE, "0.5813889" },
7367     { "root/timetz",    VT_DATE, "1.112512" },
7368     { "root/i1",        VT_I1,   "-13" },
7369     { "root/i2",        VT_I2,   "31915" },
7370     { "root/i4",        VT_I4,   "-312232" },
7371     { "root/ui1",       VT_UI1,  "123" },
7372     { "root/ui2",       VT_UI2,  "48282" },
7373     { "root/ui4",       VT_UI4,  "949281" },
7374     { "root/r4",        VT_R4,   "213124" },
7375     { "root/r8",        VT_R8,   "0.412" },
7376     { "root/float",     VT_R8,   "41221.421" },
7377     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7378     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7379     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7380     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7381     { 0 }
7382 };
7383
7384 static void test_nodeTypedValue(void)
7385 {
7386     const nodetypedvalue_t *entry = get_nodetypedvalue;
7387     IXMLDOMDocumentType *doctype, *doctype2;
7388     IXMLDOMProcessingInstruction *pi;
7389     IXMLDOMDocumentFragment *frag;
7390     IXMLDOMDocument *doc, *doc2;
7391     IXMLDOMCDATASection *cdata;
7392     IXMLDOMComment *comment;
7393     IXMLDOMNode *node;
7394     VARIANT_BOOL b;
7395     VARIANT value;
7396     HRESULT hr;
7397
7398     doc = create_document(&IID_IXMLDOMDocument);
7399     if (!doc) return;
7400
7401     b = VARIANT_FALSE;
7402     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7403     ok(hr == S_OK, "ret %08x\n", hr );
7404     ok(b == VARIANT_TRUE, "got %d\n", b);
7405
7406     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7407     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7408
7409     V_VT(&value) = VT_BSTR;
7410     V_BSTR(&value) = NULL;
7411     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7412     ok(hr == S_FALSE, "ret %08x\n", hr );
7413     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7414
7415     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7416     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7417
7418     V_VT(&value) = VT_EMPTY;
7419     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7420     ok(hr == S_FALSE, "ret %08x\n", hr );
7421     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7422
7423     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7424     ok(hr == S_OK, "ret %08x\n", hr );
7425
7426     V_VT(&value) = VT_BSTR;
7427     V_BSTR(&value) = NULL;
7428     hr = IXMLDOMNode_get_nodeValue(node, &value);
7429     ok(hr == S_FALSE, "ret %08x\n", hr );
7430     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7431
7432     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7433     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7434
7435     IXMLDOMNode_Release(node);
7436
7437     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7438     ok(hr == S_OK, "ret %08x\n", hr );
7439     {
7440         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7441
7442         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7443         ok(hr == S_OK, "ret %08x\n", hr );
7444         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7445         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7446         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7447             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7448         VariantClear(&value);
7449         IXMLDOMNode_Release(node);
7450     }
7451
7452     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7453     ok(hr == S_OK, "ret %08x\n", hr );
7454     {
7455         V_VT(&value) = VT_NULL;
7456         V_BSTR(&value) = (void*)0xdeadbeef;
7457         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7458         ok(hr == S_OK, "ret %08x\n", hr );
7459         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7460         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7461         IXMLDOMProcessingInstruction_Release(pi);
7462         VariantClear(&value);
7463     }
7464
7465     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7466     ok(hr == S_OK, "ret %08x\n", hr );
7467     {
7468         V_VT(&value) = VT_NULL;
7469         V_BSTR(&value) = (void*)0xdeadbeef;
7470         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7471         ok(hr == S_OK, "ret %08x\n", hr );
7472         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7473         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7474         IXMLDOMCDATASection_Release(cdata);
7475         VariantClear(&value);
7476     }
7477
7478     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7479     ok(hr == S_OK, "ret %08x\n", hr );
7480     {
7481         V_VT(&value) = VT_NULL;
7482         V_BSTR(&value) = (void*)0xdeadbeef;
7483         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7484         ok(hr == S_OK, "ret %08x\n", hr );
7485         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7486         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7487         IXMLDOMComment_Release(comment);
7488         VariantClear(&value);
7489     }
7490
7491     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7492     ok(hr == S_OK, "ret %08x\n", hr );
7493     {
7494         V_VT(&value) = VT_EMPTY;
7495         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7496         ok(hr == S_FALSE, "ret %08x\n", hr );
7497         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7498         IXMLDOMDocumentFragment_Release(frag);
7499     }
7500
7501     doc2 = create_document(&IID_IXMLDOMDocument);
7502
7503     b = VARIANT_FALSE;
7504     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7505     ok(hr == S_OK, "ret %08x\n", hr );
7506     ok(b == VARIANT_TRUE, "got %d\n", b);
7507
7508     EXPECT_REF(doc2, 1);
7509
7510     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7511     ok(hr == S_OK, "ret %08x\n", hr );
7512
7513     EXPECT_REF(doc2, 1);
7514     todo_wine EXPECT_REF(doctype, 2);
7515
7516     {
7517         V_VT(&value) = VT_EMPTY;
7518         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7519         ok(hr == S_FALSE, "ret %08x\n", hr );
7520         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7521     }
7522
7523     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7524     ok(hr == S_OK, "ret %08x\n", hr );
7525     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7526
7527     IXMLDOMDocumentType_Release(doctype2);
7528     IXMLDOMDocumentType_Release(doctype);
7529
7530     IXMLDOMDocument_Release(doc2);
7531
7532     while (entry->name)
7533     {
7534         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7535         ok(hr == S_OK, "ret %08x\n", hr );
7536
7537         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7538         ok(hr == S_OK, "ret %08x\n", hr );
7539         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7540
7541         if (entry->type == (VT_ARRAY|VT_UI1))
7542         {
7543             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7544                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7545         }
7546
7547         if (entry->type != VT_BSTR)
7548         {
7549            if (entry->type == VT_DATE ||
7550                entry->type == VT_R8 ||
7551                entry->type == VT_CY)
7552            {
7553                if (entry->type == VT_DATE)
7554                {
7555                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7556                    ok(hr == S_OK, "ret %08x\n", hr );
7557                }
7558                hr = VariantChangeTypeEx(&value, &value,
7559                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7560                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7561                ok(hr == S_OK, "ret %08x\n", hr );
7562            }
7563            else
7564            {
7565                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7566                ok(hr == S_OK, "ret %08x\n", hr );
7567            }
7568
7569            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7570            if (entry->type == (VT_ARRAY|VT_UI1))
7571            {
7572                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7573                   "expected %s\n", entry->value);
7574            }
7575            else
7576                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7577                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7578         }
7579         else
7580            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7581                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7582
7583         VariantClear( &value );
7584         IXMLDOMNode_Release(node);
7585
7586         entry++;
7587     }
7588
7589     IXMLDOMDocument_Release(doc);
7590     free_bstrs();
7591 }
7592
7593 static void test_TransformWithLoadingLocalFile(void)
7594 {
7595     IXMLDOMDocument *doc;
7596     IXMLDOMDocument *xsl;
7597     IXMLDOMNode *pNode;
7598     VARIANT_BOOL bSucc;
7599     HRESULT hr;
7600     HANDLE file;
7601     DWORD dwWritten;
7602     char lpPathBuffer[MAX_PATH];
7603     int i;
7604
7605     /* Create a Temp File. */
7606     GetTempPathA(MAX_PATH, lpPathBuffer);
7607     strcat(lpPathBuffer, "customers.xml" );
7608
7609     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7610     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7611     if(file == INVALID_HANDLE_VALUE)
7612         return;
7613
7614     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7615     CloseHandle(file);
7616
7617     /* Correct path to not include a escape character. */
7618     for(i=0; i < strlen(lpPathBuffer); i++)
7619     {
7620         if(lpPathBuffer[i] == '\\')
7621             lpPathBuffer[i] = '/';
7622     }
7623
7624     doc = create_document(&IID_IXMLDOMDocument);
7625     if (!doc) return;
7626
7627     xsl = create_document(&IID_IXMLDOMDocument);
7628     if (!xsl)
7629     {
7630         IXMLDOMDocument2_Release(doc);
7631         return;
7632     }
7633
7634     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7635     ok(hr == S_OK, "ret %08x\n", hr );
7636     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7637     if(bSucc == VARIANT_TRUE)
7638     {
7639         BSTR sXSL;
7640         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7641         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7642         BSTR sFileName = _bstr_(lpPathBuffer);
7643         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7644
7645         sXSL = SysAllocStringLen(NULL, nLegnth);
7646         lstrcpyW(sXSL, sPart1);
7647         lstrcatW(sXSL, sFileName);
7648         lstrcatW(sXSL, sPart2);
7649
7650         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7651         ok(hr == S_OK, "ret %08x\n", hr );
7652         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7653         if(bSucc == VARIANT_TRUE)
7654         {
7655             BSTR sResult;
7656
7657             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7658             ok(hr == S_OK, "ret %08x\n", hr );
7659             if(hr == S_OK)
7660             {
7661                 /* This will load the temp file via the XSL */
7662                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7663                 ok(hr == S_OK, "ret %08x\n", hr );
7664                 if(hr == S_OK)
7665                 {
7666                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7667                     SysFreeString(sResult);
7668                 }
7669
7670                 IXMLDOMNode_Release(pNode);
7671             }
7672         }
7673
7674         SysFreeString(sXSL);
7675     }
7676
7677     IXMLDOMDocument_Release(doc);
7678     IXMLDOMDocument_Release(xsl);
7679
7680     DeleteFile(lpPathBuffer);
7681     free_bstrs();
7682 }
7683
7684 static void test_put_nodeValue(void)
7685 {
7686     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7687     IXMLDOMDocument *doc;
7688     IXMLDOMText *text;
7689     IXMLDOMEntityReference *entityref;
7690     IXMLDOMAttribute *attr;
7691     IXMLDOMNode *node;
7692     HRESULT hr;
7693     VARIANT data, type;
7694
7695     doc = create_document(&IID_IXMLDOMDocument);
7696     if (!doc) return;
7697
7698     /* test for unsupported types */
7699     /* NODE_DOCUMENT */
7700     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7701     ok(hr == S_OK, "ret %08x\n", hr );
7702     V_VT(&data) = VT_BSTR;
7703     V_BSTR(&data) = _bstr_("one two three");
7704     hr = IXMLDOMNode_put_nodeValue(node, data);
7705     ok(hr == E_FAIL, "ret %08x\n", hr );
7706     IXMLDOMNode_Release(node);
7707
7708     /* NODE_DOCUMENT_FRAGMENT */
7709     V_VT(&type) = VT_I1;
7710     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7711     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7712     ok(hr == S_OK, "ret %08x\n", hr );
7713     V_VT(&data) = VT_BSTR;
7714     V_BSTR(&data) = _bstr_("one two three");
7715     hr = IXMLDOMNode_put_nodeValue(node, data);
7716     ok(hr == E_FAIL, "ret %08x\n", hr );
7717     IXMLDOMNode_Release(node);
7718
7719     /* NODE_ELEMENT */
7720     V_VT(&type) = VT_I1;
7721     V_I1(&type) = NODE_ELEMENT;
7722     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7723     ok(hr == S_OK, "ret %08x\n", hr );
7724     V_VT(&data) = VT_BSTR;
7725     V_BSTR(&data) = _bstr_("one two three");
7726     hr = IXMLDOMNode_put_nodeValue(node, data);
7727     ok(hr == E_FAIL, "ret %08x\n", hr );
7728     IXMLDOMNode_Release(node);
7729
7730     /* NODE_ENTITY_REFERENCE */
7731     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7732     ok(hr == S_OK, "ret %08x\n", hr );
7733
7734     V_VT(&data) = VT_BSTR;
7735     V_BSTR(&data) = _bstr_("one two three");
7736     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7737     ok(hr == E_FAIL, "ret %08x\n", hr );
7738
7739     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7740     ok(hr == S_OK, "ret %08x\n", hr );
7741     V_VT(&data) = VT_BSTR;
7742     V_BSTR(&data) = _bstr_("one two three");
7743     hr = IXMLDOMNode_put_nodeValue(node, data);
7744     ok(hr == E_FAIL, "ret %08x\n", hr );
7745     IXMLDOMNode_Release(node);
7746     IXMLDOMEntityReference_Release(entityref);
7747
7748     /* supported types */
7749     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7750     ok(hr == S_OK, "ret %08x\n", hr );
7751     V_VT(&data) = VT_BSTR;
7752     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7753     hr = IXMLDOMText_put_nodeValue(text, data);
7754     ok(hr == S_OK, "ret %08x\n", hr );
7755     IXMLDOMText_Release(text);
7756
7757     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7758     ok(hr == S_OK, "ret %08x\n", hr );
7759     V_VT(&data) = VT_BSTR;
7760     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7761     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7762     ok(hr == S_OK, "ret %08x\n", hr );
7763     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7764     ok(hr == S_OK, "ret %08x\n", hr );
7765     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7766         wine_dbgstr_w(V_BSTR(&data)));
7767     VariantClear(&data);
7768     IXMLDOMAttribute_Release(attr);
7769
7770     free_bstrs();
7771
7772     IXMLDOMDocument_Release(doc);
7773 }
7774
7775 static void test_document_IObjectSafety(void)
7776 {
7777     IXMLDOMDocument *doc;
7778     IObjectSafety *safety;
7779     HRESULT hr;
7780
7781     doc = create_document(&IID_IXMLDOMDocument);
7782     if (!doc) return;
7783
7784     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7785     ok(hr == S_OK, "ret %08x\n", hr );
7786
7787     test_IObjectSafety_common(safety);
7788
7789     IObjectSafety_Release(safety);
7790
7791     IXMLDOMDocument_Release(doc);
7792 }
7793
7794 typedef struct _property_test_t {
7795     const GUID *guid;
7796     const char *clsid;
7797     const char *property;
7798     const char *value;
7799 } property_test_t;
7800
7801 static const property_test_t properties_test_data[] = {
7802     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7803     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7804     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7805     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7806     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7807     { 0 }
7808 };
7809
7810 static void test_default_properties(void)
7811 {
7812     const property_test_t *entry = properties_test_data;
7813
7814     while (entry->guid)
7815     {
7816         IXMLDOMDocument2 *doc;
7817         VARIANT var;
7818         HRESULT hr;
7819
7820         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7821         if (hr != S_OK)
7822         {
7823             win_skip("can't create %s instance\n", entry->clsid);
7824             entry++;
7825             continue;
7826         }
7827
7828         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7829         ok(hr == S_OK, "got 0x%08x\n", hr);
7830         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7831            entry->value, entry->clsid);
7832         VariantClear(&var);
7833
7834         IXMLDOMDocument2_Release(doc);
7835
7836         entry++;
7837     }
7838 }
7839
7840 typedef struct {
7841     const char *query;
7842     const char *list;
7843 } xslpattern_test_t;
7844
7845 static const xslpattern_test_t xslpattern_test[] = {
7846     { "root//elem[0]", "E1.E2.D1" },
7847     { "root//elem[index()=1]", "E2.E2.D1" },
7848     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7849     { "root//elem[end()]", "E4.E2.D1" },
7850     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7851     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7852     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7853     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7854     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7855     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7856     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7857     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7858     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7859     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7860     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7861     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7862     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7863     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7864     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7865     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7866     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7867     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7868     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7869     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7870     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7871     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7872     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7873     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7874     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7875     { NULL }
7876 };
7877
7878 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7879     /* prefixes don't need to be registered, you may use them as they are in the doc */
7880     { "//bar:x", "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1" },
7881     /* prefixes must be explicitly specified in the name */
7882     { "//foo:elem", "" },
7883     { "//foo:c", "E3.E4.E2.D1" },
7884     { NULL }
7885 };
7886
7887 static const xslpattern_test_t xslpattern_test_func[] = {
7888     { "attribute()", "" },
7889     { "attribute('depth')", "" },
7890     { "root/attribute('depth')", "A'depth'.E3.D1" },
7891     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7892     { "//x//attribute(id)", NULL },
7893     { "//x//attribute('id')", "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1" },
7894     { "comment()", "C2.D1" },
7895     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7896     { "element()", "E3.D1" },
7897     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7898     { "//element(a)", NULL },
7899     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7900     { "node()", "P1.D1 C2.D1 E3.D1" },
7901     { "//x/node()", "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7902     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7903     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7904     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7905     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7906     { "pi()", "P1.D1" },
7907     { "//y/pi()", "P1.E4.E3.D1" },
7908     { "root/textnode()", "T2.E3.D1" },
7909     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7910     { NULL }
7911 };
7912
7913 static void test_XSLPattern(void)
7914 {
7915     const xslpattern_test_t *ptr = xslpattern_test;
7916     IXMLDOMDocument2 *doc;
7917     IXMLDOMNodeList *list;
7918     VARIANT_BOOL b;
7919     HRESULT hr;
7920     LONG len;
7921
7922     doc = create_document(&IID_IXMLDOMDocument2);
7923     if (!doc) return;
7924
7925     b = VARIANT_FALSE;
7926     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7927     EXPECT_HR(hr, S_OK);
7928     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7929
7930     /* switch to XSLPattern */
7931     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7932     EXPECT_HR(hr, S_OK);
7933
7934     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7935     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7936     EXPECT_HR(hr, S_OK);
7937
7938     len = 0;
7939     hr = IXMLDOMNodeList_get_length(list, &len);
7940     EXPECT_HR(hr, S_OK);
7941     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7942     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7943     IXMLDOMNodeList_Release(list);
7944
7945     while (ptr->query)
7946     {
7947         list = NULL;
7948         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7949         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7950         len = 0;
7951         hr = IXMLDOMNodeList_get_length(list, &len);
7952         ok(len != 0, "query=%s, empty list\n", ptr->query);
7953         if (len)
7954             expect_list_and_release(list, ptr->list);
7955
7956         ptr++;
7957     }
7958
7959     /* namespace handling */
7960     /* no registered namespaces */
7961     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7962     EXPECT_HR(hr, S_OK);
7963
7964     ptr = xslpattern_test_no_ns;
7965     while (ptr->query)
7966     {
7967         list = NULL;
7968         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7969         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7970
7971         if (*ptr->list)
7972         {
7973             len = 0;
7974             hr = IXMLDOMNodeList_get_length(list, &len);
7975             EXPECT_HR(hr, S_OK);
7976             ok(len != 0, "query=%s, empty list\n", ptr->query);
7977         }
7978         else
7979         {
7980             len = 1;
7981             hr = IXMLDOMNodeList_get_length(list, &len);
7982             EXPECT_HR(hr, S_OK);
7983             ok(len == 0, "query=%s, empty list\n", ptr->query);
7984         }
7985         if (len)
7986             expect_list_and_release(list, ptr->list);
7987
7988         ptr++;
7989     }
7990
7991     /* explicitly register prefix foo */
7992     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7993
7994     /* now we get the same behavior as XPath */
7995     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7996     EXPECT_HR(hr, S_OK);
7997     len = 0;
7998     hr = IXMLDOMNodeList_get_length(list, &len);
7999     EXPECT_HR(hr, S_OK);
8000     ok(len != 0, "expected filled list\n");
8001     if (len)
8002         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8003
8004     /* set prefix foo to some nonexistent namespace */
8005     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8006     EXPECT_HR(hr, S_OK);
8007
8008     /* the registered prefix takes precedence */
8009     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8010     EXPECT_HR(hr, S_OK);
8011     len = 0;
8012     hr = IXMLDOMNodeList_get_length(list, &len);
8013     EXPECT_HR(hr, S_OK);
8014     ok(len == 0, "expected empty list\n");
8015     IXMLDOMNodeList_Release(list);
8016
8017     IXMLDOMDocument2_Release(doc);
8018
8019     doc = create_document(&IID_IXMLDOMDocument2);
8020     if (!doc) return;
8021
8022     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8023     EXPECT_HR(hr, S_OK);
8024     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8025
8026     ptr = xslpattern_test_func;
8027     while (ptr->query)
8028     {
8029         list = NULL;
8030         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8031         if (ptr->list)
8032         {
8033             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8034             len = 0;
8035             hr = IXMLDOMNodeList_get_length(list, &len);
8036             if (*ptr->list)
8037             {
8038                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8039                 if (len)
8040                     expect_list_and_release(list, ptr->list);
8041             }
8042             else
8043                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8044         }
8045         else
8046             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8047
8048         ptr++;
8049     }
8050
8051     IXMLDOMDocument2_Release(doc);
8052     free_bstrs();
8053 }
8054
8055 static void test_splitText(void)
8056 {
8057     IXMLDOMCDATASection *cdata;
8058     IXMLDOMElement *root;
8059     IXMLDOMDocument *doc;
8060     IXMLDOMText *text, *text2;
8061     IXMLDOMNode *node;
8062     VARIANT var;
8063     VARIANT_BOOL success;
8064     LONG length;
8065     HRESULT hr;
8066
8067     doc = create_document(&IID_IXMLDOMDocument);
8068     if (!doc) return;
8069
8070     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8071     ok(hr == S_OK, "got 0x%08x\n", hr);
8072
8073     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8074     ok(hr == S_OK, "got 0x%08x\n", hr);
8075
8076     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8077     ok(hr == S_OK, "got 0x%08x\n", hr);
8078
8079     V_VT(&var) = VT_EMPTY;
8080     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8081     ok(hr == S_OK, "got 0x%08x\n", hr);
8082
8083     length = 0;
8084     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8085     ok(hr == S_OK, "got 0x%08x\n", hr);
8086     ok(length > 0, "got %d\n", length);
8087
8088     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8089     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8090
8091     text = (void*)0xdeadbeef;
8092     /* negative offset */
8093     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8094     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8095     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8096
8097     text = (void*)0xdeadbeef;
8098     /* offset outside data */
8099     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8100     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8101     ok(text == 0, "got %p\n", text);
8102
8103     text = (void*)0xdeadbeef;
8104     /* offset outside data */
8105     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8106     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8107     ok(text == 0, "got %p\n", text);
8108
8109     /* no empty node created */
8110     node = (void*)0xdeadbeef;
8111     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8112     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8113     ok(node == 0, "got %p\n", text);
8114
8115     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8116     ok(hr == S_OK, "got 0x%08x\n", hr);
8117
8118     length = 0;
8119     hr = IXMLDOMText_get_length(text, &length);
8120     ok(hr == S_OK, "got 0x%08x\n", hr);
8121     ok(length == 7, "got %d\n", length);
8122
8123     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8124     ok(hr == S_OK, "got 0x%08x\n", hr);
8125     IXMLDOMNode_Release(node);
8126
8127     /* split new text node */
8128     hr = IXMLDOMText_get_length(text, &length);
8129     ok(hr == S_OK, "got 0x%08x\n", hr);
8130
8131     node = (void*)0xdeadbeef;
8132     hr = IXMLDOMText_get_nextSibling(text, &node);
8133     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8134     ok(node == 0, "got %p\n", text);
8135
8136     hr = IXMLDOMText_splitText(text, 0, NULL);
8137     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8138
8139     text2 = (void*)0xdeadbeef;
8140     /* negative offset */
8141     hr = IXMLDOMText_splitText(text, -1, &text2);
8142     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8143     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8144
8145     text2 = (void*)0xdeadbeef;
8146     /* offset outside data */
8147     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8148     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8149     ok(text2 == 0, "got %p\n", text2);
8150
8151     text2 = (void*)0xdeadbeef;
8152     /* offset outside data */
8153     hr = IXMLDOMText_splitText(text, length, &text2);
8154     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8155     ok(text2 == 0, "got %p\n", text);
8156
8157     text2 = 0;
8158     hr = IXMLDOMText_splitText(text, 4, &text2);
8159     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8160     if (text2) IXMLDOMText_Release(text2);
8161
8162     node = 0;
8163     hr = IXMLDOMText_get_nextSibling(text, &node);
8164     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8165     if (node) IXMLDOMNode_Release(node);
8166
8167     IXMLDOMText_Release(text);
8168     IXMLDOMElement_Release(root);
8169     IXMLDOMCDATASection_Release(cdata);
8170     free_bstrs();
8171 }
8172
8173 typedef struct {
8174     const char *name;
8175     const char *uri;
8176     HRESULT hr;
8177 } ns_item_t;
8178
8179 /* default_ns_doc used */
8180 static const ns_item_t qualified_item_tests[] = {
8181     { "xml:lang", NULL, S_FALSE },
8182     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8183     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8184     { "ns:b", NULL, S_FALSE },
8185     { "ns:b", "nshref", S_FALSE },
8186     { "b", "nshref", S_OK },
8187     { "d", NULL, S_OK },
8188     { NULL }
8189 };
8190
8191 static const ns_item_t named_item_tests[] = {
8192     { "xml:lang", NULL, S_OK },
8193     { "lang", NULL, S_FALSE },
8194     { "ns:b", NULL, S_OK },
8195     { "b", NULL, S_FALSE },
8196     { "d", NULL, S_OK },
8197     { NULL }
8198 };
8199
8200 static void test_getQualifiedItem(void)
8201 {
8202     IXMLDOMNode *pr_node, *node;
8203     IXMLDOMNodeList *root_list;
8204     IXMLDOMNamedNodeMap *map;
8205     IXMLDOMElement *element;
8206     const ns_item_t* ptr;
8207     IXMLDOMDocument *doc;
8208     VARIANT_BOOL b;
8209     HRESULT hr;
8210     LONG len;
8211
8212     doc = create_document(&IID_IXMLDOMDocument);
8213     if (!doc) return;
8214
8215     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8216     EXPECT_HR(hr, S_OK);
8217     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8218
8219     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8220     EXPECT_HR(hr, S_OK);
8221
8222     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8223     EXPECT_HR(hr, S_OK);
8224
8225     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8226     EXPECT_HR(hr, S_OK);
8227     IXMLDOMNodeList_Release(root_list);
8228
8229     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8230     EXPECT_HR(hr, S_OK);
8231     IXMLDOMNode_Release(pr_node);
8232
8233     len = 0;
8234     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8235     EXPECT_HR(hr, S_OK);
8236     ok( len == 3, "length %d\n", len);
8237
8238     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8239     EXPECT_HR(hr, E_INVALIDARG);
8240
8241     node = (void*)0xdeadbeef;
8242     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8243     EXPECT_HR(hr, E_INVALIDARG);
8244     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8245
8246     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8247     EXPECT_HR(hr, E_INVALIDARG);
8248
8249     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8250     EXPECT_HR(hr, S_OK);
8251
8252     IXMLDOMNode_Release(node);
8253     IXMLDOMNamedNodeMap_Release(map);
8254     IXMLDOMElement_Release(element);
8255
8256     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8257     EXPECT_HR(hr, S_OK);
8258
8259     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8260     EXPECT_HR(hr, S_OK);
8261
8262     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8263     EXPECT_HR(hr, S_OK);
8264     IXMLDOMNode_Release(node);
8265
8266     hr = IXMLDOMElement_get_attributes(element, &map);
8267     EXPECT_HR(hr, S_OK);
8268
8269     ptr = qualified_item_tests;
8270     while (ptr->name)
8271     {
8272        node = (void*)0xdeadbeef;
8273        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8274        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8275        if (hr == S_OK)
8276            IXMLDOMNode_Release(node);
8277        else
8278            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8279        ptr++;
8280     }
8281
8282     ptr = named_item_tests;
8283     while (ptr->name)
8284     {
8285        node = (void*)0xdeadbeef;
8286        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8287        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8288        if (hr == S_OK)
8289            IXMLDOMNode_Release(node);
8290        else
8291            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8292        ptr++;
8293     }
8294
8295     IXMLDOMNamedNodeMap_Release(map);
8296
8297     IXMLDOMElement_Release(element);
8298     IXMLDOMDocument_Release(doc);
8299     free_bstrs();
8300 }
8301
8302 static void test_removeQualifiedItem(void)
8303 {
8304     IXMLDOMDocument *doc;
8305     IXMLDOMElement *element;
8306     IXMLDOMNode *pr_node, *node;
8307     IXMLDOMNodeList *root_list;
8308     IXMLDOMNamedNodeMap *map;
8309     VARIANT_BOOL b;
8310     LONG len;
8311     HRESULT hr;
8312
8313     doc = create_document(&IID_IXMLDOMDocument);
8314     if (!doc) return;
8315
8316     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8317     ok( hr == S_OK, "loadXML failed\n");
8318     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8319
8320     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8321     ok( hr == S_OK, "ret %08x\n", hr);
8322
8323     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8324     ok( hr == S_OK, "ret %08x\n", hr);
8325
8326     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8327     ok( hr == S_OK, "ret %08x\n", hr);
8328     IXMLDOMNodeList_Release(root_list);
8329
8330     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8331     ok( hr == S_OK, "ret %08x\n", hr);
8332     IXMLDOMNode_Release(pr_node);
8333
8334     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8335     ok( hr == S_OK, "ret %08x\n", hr);
8336     ok( len == 3, "length %d\n", len);
8337
8338     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8339     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8340
8341     node = (void*)0xdeadbeef;
8342     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8343     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8344     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8345
8346     /* out pointer is optional */
8347     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8348     ok( hr == S_OK, "ret %08x\n", hr);
8349
8350     /* already removed */
8351     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8352     ok( hr == S_FALSE, "ret %08x\n", hr);
8353
8354     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8355     ok( hr == S_OK, "ret %08x\n", hr);
8356     IXMLDOMNode_Release(node);
8357
8358     IXMLDOMNamedNodeMap_Release( map );
8359     IXMLDOMElement_Release( element );
8360     IXMLDOMDocument_Release( doc );
8361     free_bstrs();
8362 }
8363
8364 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8365 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8366 {
8367     VARIANT_BOOL b;
8368     VARIANT var;
8369     HRESULT hr;
8370
8371     VariantInit(&var);
8372     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8373     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8374     VariantClear(&var);
8375
8376     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8377     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8378     VariantClear(&var);
8379
8380     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8381     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8382
8383     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8384     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8385     VariantClear(&var);
8386 }
8387
8388 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8389 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8390 {
8391     VARIANT_BOOL b;
8392     VARIANT var;
8393
8394     VariantInit(&var);
8395     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8396     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8397     VariantClear(&var);
8398
8399     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8400     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8401     VariantClear(&var);
8402
8403     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8404     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8405
8406     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8407     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8408     VariantClear(&var);
8409 }
8410
8411 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8412 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8413 {
8414     VARIANT var;
8415
8416     VariantInit(&var);
8417     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8418     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8419     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8420     V_VT(&var) = VT_DISPATCH;
8421     V_DISPATCH(&var) = NULL;
8422     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8423     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8424     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8425     VariantClear(&var);
8426 }
8427
8428 #define unset_props(doc) _unset_props(__LINE__, doc)
8429 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8430 {
8431     VARIANT var;
8432
8433     VariantInit(&var);
8434     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8435     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8436     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8437     V_VT(&var) = VT_NULL;
8438     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8439     VariantClear(&var);
8440 }
8441
8442 static void test_get_ownerDocument(void)
8443 {
8444     IXMLDOMDocument *doc1, *doc2, *doc3;
8445     IXMLDOMDocument2 *doc, *doc_owner;
8446     IXMLDOMNode *node;
8447     IXMLDOMSchemaCollection *cache;
8448     VARIANT_BOOL b;
8449     VARIANT var;
8450
8451     doc = create_document(&IID_IXMLDOMDocument2);
8452     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8453     if (!doc || !cache)
8454     {
8455         if (doc) IXMLDOMDocument2_Release(doc);
8456         if (cache) IXMLDOMSchemaCollection_Release(cache);
8457         return;
8458     }
8459
8460     VariantInit(&var);
8461
8462     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8463     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8464
8465     check_default_props(doc);
8466
8467     /* set properties and check that new instances use them */
8468     set_props(doc, cache);
8469     check_set_props(doc);
8470
8471     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8472     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8473
8474     /* new interface keeps props */
8475     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8476     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8477     check_set_props(doc_owner);
8478     IXMLDOMDocument2_Release(doc_owner);
8479
8480     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8481     IXMLDOMNode_Release(node);
8482
8483     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8484
8485     /* reload */
8486     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8487     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8488
8489     /* properties retained even after reload */
8490     check_set_props(doc);
8491
8492     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8493     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8494     IXMLDOMNode_Release(node);
8495
8496     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8497     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8498     check_set_props(doc_owner);
8499
8500     /* changing properties for one instance changes them for all */
8501     unset_props(doc_owner);
8502     check_default_props(doc_owner);
8503     check_default_props(doc);
8504
8505     IXMLDOMSchemaCollection_Release(cache);
8506     IXMLDOMDocument_Release(doc1);
8507     IXMLDOMDocument_Release(doc2);
8508     IXMLDOMDocument_Release(doc3);
8509     IXMLDOMDocument2_Release(doc);
8510     IXMLDOMDocument2_Release(doc_owner);
8511     free_bstrs();
8512 }
8513
8514 static void test_setAttributeNode(void)
8515 {
8516     IXMLDOMDocument *doc, *doc2;
8517     IXMLDOMElement *elem, *elem2;
8518     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8519     VARIANT_BOOL b;
8520     HRESULT hr;
8521     VARIANT v;
8522     BSTR str;
8523     ULONG ref1, ref2;
8524
8525     doc = create_document(&IID_IXMLDOMDocument);
8526     if (!doc) return;
8527
8528     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8529     ok( hr == S_OK, "loadXML failed\n");
8530     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8531
8532     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8533     ok( hr == S_OK, "got 0x%08x\n", hr);
8534
8535     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8536     ok( hr == S_OK, "got 0x%08x\n", hr);
8537     ok( elem2 != elem, "got same instance\n");
8538
8539     ret_attr = (void*)0xdeadbeef;
8540     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8541     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8542     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8543
8544     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8545     ok( hr == S_OK, "got 0x%08x\n", hr);
8546
8547     ref1 = IXMLDOMElement_AddRef(elem);
8548     IXMLDOMElement_Release(elem);
8549
8550     ret_attr = (void*)0xdeadbeef;
8551     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8552     ok( hr == S_OK, "got 0x%08x\n", hr);
8553     ok( ret_attr == NULL, "got %p\n", ret_attr);
8554
8555     /* no reference added */
8556     ref2 = IXMLDOMElement_AddRef(elem);
8557     IXMLDOMElement_Release(elem);
8558     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8559
8560     EXPECT_CHILDREN(elem);
8561     EXPECT_CHILDREN(elem2);
8562
8563     IXMLDOMElement_Release(elem2);
8564
8565     attr2 = NULL;
8566     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8567     ok( hr == S_OK, "got 0x%08x\n", hr);
8568     ok( attr2 != attr, "got same instance %p\n", attr2);
8569     IXMLDOMAttribute_Release(attr2);
8570
8571     /* try to add it another time */
8572     ret_attr = (void*)0xdeadbeef;
8573     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8574     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8575     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8576
8577     IXMLDOMElement_Release(elem);
8578
8579     /* initially used element is released, attribute still 'has' a container */
8580     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8581     ok( hr == S_OK, "got 0x%08x\n", hr);
8582     ret_attr = (void*)0xdeadbeef;
8583     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8584     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8585     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8586     IXMLDOMElement_Release(elem);
8587
8588     /* add attribute already attached to another document */
8589     doc2 = create_document(&IID_IXMLDOMDocument);
8590
8591     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8592     ok( hr == S_OK, "loadXML failed\n");
8593     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8594
8595     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8596     ok( hr == S_OK, "got 0x%08x\n", hr);
8597     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8598     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8599     IXMLDOMElement_Release(elem);
8600
8601     IXMLDOMAttribute_Release(attr);
8602
8603     /* create element, add attribute, see if it's copied or linked */
8604     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8605     ok( hr == S_OK, "got 0x%08x\n", hr);
8606
8607     attr = NULL;
8608     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8609     ok(hr == S_OK, "got 0x%08x\n", hr);
8610     ok(attr != NULL, "got %p\n", attr);
8611
8612     ref1 = IXMLDOMAttribute_AddRef(attr);
8613     IXMLDOMAttribute_Release(attr);
8614
8615     V_VT(&v) = VT_BSTR;
8616     V_BSTR(&v) = _bstr_("attrvalue1");
8617     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8618     ok( hr == S_OK, "got 0x%08x\n", hr);
8619
8620     str = NULL;
8621     hr = IXMLDOMAttribute_get_xml(attr, &str);
8622     ok( hr == S_OK, "got 0x%08x\n", hr);
8623     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8624         "got %s\n", wine_dbgstr_w(str));
8625     SysFreeString(str);
8626
8627     ret_attr = (void*)0xdeadbeef;
8628     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8629     ok(hr == S_OK, "got 0x%08x\n", hr);
8630     ok(ret_attr == NULL, "got %p\n", ret_attr);
8631
8632     /* attribute reference increased */
8633     ref2 = IXMLDOMAttribute_AddRef(attr);
8634     IXMLDOMAttribute_Release(attr);
8635     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8636
8637     hr = IXMLDOMElement_get_xml(elem, &str);
8638     ok( hr == S_OK, "got 0x%08x\n", hr);
8639     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8640         "got %s\n", wine_dbgstr_w(str));
8641     SysFreeString(str);
8642
8643     V_VT(&v) = VT_BSTR;
8644     V_BSTR(&v) = _bstr_("attrvalue2");
8645     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8646     ok( hr == S_OK, "got 0x%08x\n", hr);
8647
8648     hr = IXMLDOMElement_get_xml(elem, &str);
8649     ok( hr == S_OK, "got 0x%08x\n", hr);
8650     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8651         "got %s\n", wine_dbgstr_w(str));
8652     SysFreeString(str);
8653
8654     IXMLDOMElement_Release(elem);
8655     IXMLDOMAttribute_Release(attr);
8656     IXMLDOMDocument_Release(doc2);
8657     IXMLDOMDocument_Release(doc);
8658     free_bstrs();
8659 }
8660
8661 static void test_createNode(void)
8662 {
8663     IXMLDOMDocument *doc;
8664     IXMLDOMElement *elem;
8665     IXMLDOMNode *node;
8666     VARIANT v, var;
8667     BSTR prefix, str;
8668     HRESULT hr;
8669     ULONG ref;
8670
8671     doc = create_document(&IID_IXMLDOMDocument);
8672     if (!doc) return;
8673
8674     EXPECT_REF(doc, 1);
8675
8676     /* reference count tests */
8677     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8678     ok( hr == S_OK, "got 0x%08x\n", hr);
8679
8680     /* initial reference is 2 */
8681 todo_wine {
8682     EXPECT_REF(elem, 2);
8683     ref = IXMLDOMElement_Release(elem);
8684     ok(ref == 1, "got %d\n", ref);
8685     /* it's released already, attempt to release now will crash it */
8686 }
8687
8688     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8689     ok( hr == S_OK, "got 0x%08x\n", hr);
8690     todo_wine EXPECT_REF(elem, 2);
8691     IXMLDOMDocument_Release(doc);
8692     todo_wine EXPECT_REF(elem, 2);
8693     IXMLDOMElement_Release(elem);
8694
8695     doc = create_document(&IID_IXMLDOMDocument);
8696
8697     /* NODE_ELEMENT nodes */
8698     /* 1. specified namespace */
8699     V_VT(&v) = VT_I4;
8700     V_I4(&v) = NODE_ELEMENT;
8701
8702     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8703     ok( hr == S_OK, "got 0x%08x\n", hr);
8704     prefix = NULL;
8705     hr = IXMLDOMNode_get_prefix(node, &prefix);
8706     ok( hr == S_OK, "got 0x%08x\n", hr);
8707     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8708     SysFreeString(prefix);
8709     IXMLDOMNode_Release(node);
8710
8711     /* 2. default namespace */
8712     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8713     ok( hr == S_OK, "got 0x%08x\n", hr);
8714     prefix = (void*)0xdeadbeef;
8715     hr = IXMLDOMNode_get_prefix(node, &prefix);
8716     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8717     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8718     /* check dump */
8719     hr = IXMLDOMNode_get_xml(node, &str);
8720     ok( hr == S_OK, "got 0x%08x\n", hr);
8721     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8722         "got %s\n", wine_dbgstr_w(str));
8723     SysFreeString(str);
8724
8725     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8726     ok( hr == S_OK, "got 0x%08x\n", hr);
8727
8728     V_VT(&var) = VT_BSTR;
8729     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8730     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8731     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8732
8733     str = NULL;
8734     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8735     ok( hr == S_OK, "got 0x%08x\n", hr);
8736     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8737     SysFreeString(str);
8738
8739     IXMLDOMElement_Release(elem);
8740     IXMLDOMNode_Release(node);
8741
8742     IXMLDOMDocument_Release(doc);
8743     free_bstrs();
8744 }
8745
8746 static const char get_prefix_doc[] =
8747     "<?xml version=\"1.0\" ?>"
8748     "<a xmlns:ns1=\"ns1 href\" />";
8749
8750 static void test_get_prefix(void)
8751 {
8752     IXMLDOMDocumentFragment *fragment;
8753     IXMLDOMCDATASection *cdata;
8754     IXMLDOMElement *element;
8755     IXMLDOMComment *comment;
8756     IXMLDOMDocument *doc;
8757     VARIANT_BOOL b;
8758     HRESULT hr;
8759     BSTR str;
8760
8761     doc = create_document(&IID_IXMLDOMDocument);
8762     if (!doc) return;
8763
8764     /* nodes that can't support prefix */
8765     /* 1. document */
8766     str = (void*)0xdeadbeef;
8767     hr = IXMLDOMDocument_get_prefix(doc, &str);
8768     EXPECT_HR(hr, S_FALSE);
8769     ok(str == NULL, "got %p\n", str);
8770
8771     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8772     EXPECT_HR(hr, E_INVALIDARG);
8773
8774     /* 2. cdata */
8775     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8776     ok(hr == S_OK, "got %08x\n", hr );
8777
8778     str = (void*)0xdeadbeef;
8779     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8780     ok(hr == S_FALSE, "got %08x\n", hr);
8781     ok( str == 0, "got %p\n", str);
8782
8783     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8784     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8785     IXMLDOMCDATASection_Release(cdata);
8786
8787     /* 3. comment */
8788     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8789     ok(hr == S_OK, "got %08x\n", hr );
8790
8791     str = (void*)0xdeadbeef;
8792     hr = IXMLDOMComment_get_prefix(comment, &str);
8793     ok(hr == S_FALSE, "got %08x\n", hr);
8794     ok( str == 0, "got %p\n", str);
8795
8796     hr = IXMLDOMComment_get_prefix(comment, NULL);
8797     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8798     IXMLDOMComment_Release(comment);
8799
8800     /* 4. fragment */
8801     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8802     ok(hr == S_OK, "got %08x\n", hr );
8803
8804     str = (void*)0xdeadbeef;
8805     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8806     ok(hr == S_FALSE, "got %08x\n", hr);
8807     ok( str == 0, "got %p\n", str);
8808
8809     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8810     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8811     IXMLDOMDocumentFragment_Release(fragment);
8812
8813     /* no prefix */
8814     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8815     ok( hr == S_OK, "got 0x%08x\n", hr);
8816
8817     hr = IXMLDOMElement_get_prefix(element, NULL);
8818     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8819
8820     str = (void*)0xdeadbeef;
8821     hr = IXMLDOMElement_get_prefix(element, &str);
8822     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8823     ok( str == 0, "got %p\n", str);
8824
8825     IXMLDOMElement_Release(element);
8826
8827     /* with prefix */
8828     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8829     ok( hr == S_OK, "got 0x%08x\n", hr);
8830
8831     str = (void*)0xdeadbeef;
8832     hr = IXMLDOMElement_get_prefix(element, &str);
8833     ok( hr == S_OK, "got 0x%08x\n", hr);
8834     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8835     SysFreeString(str);
8836
8837     str = (void*)0xdeadbeef;
8838     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8839     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8840     ok( str == 0, "got %p\n", str);
8841
8842     IXMLDOMElement_Release(element);
8843
8844     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8845     EXPECT_HR(hr, S_OK);
8846
8847     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8848     EXPECT_HR(hr, S_OK);
8849
8850     str = (void*)0xdeadbeef;
8851     hr = IXMLDOMElement_get_prefix(element, &str);
8852     EXPECT_HR(hr, S_FALSE);
8853     ok(str == NULL, "got %p\n", str);
8854
8855     str = (void*)0xdeadbeef;
8856     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8857     EXPECT_HR(hr, S_FALSE);
8858     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8859
8860     IXMLDOMDocument_Release(doc);
8861     free_bstrs();
8862 }
8863
8864 static void test_selectSingleNode(void)
8865 {
8866     IXMLDOMDocument *doc;
8867     IXMLDOMNodeList *list;
8868     IXMLDOMNode *node;
8869     VARIANT_BOOL b;
8870     HRESULT hr;
8871     LONG len;
8872
8873     doc = create_document(&IID_IXMLDOMDocument);
8874     if (!doc) return;
8875
8876     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8877     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8878
8879     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8880     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8881
8882     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8883     ok( hr == S_OK, "loadXML failed\n");
8884     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8885
8886     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8887     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8888
8889     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8890     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8891
8892     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8893     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8894
8895     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8896     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8897
8898     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8899     ok(hr == S_OK, "got 0x%08x\n", hr);
8900     IXMLDOMNode_Release(node);
8901
8902     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8903     ok(hr == S_OK, "got 0x%08x\n", hr);
8904     IXMLDOMNodeList_Release(list);
8905
8906     list = (void*)0xdeadbeef;
8907     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8908     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8909     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8910
8911     node = (void*)0xdeadbeef;
8912     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8913     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8914     ok(node == 0, "got %p\n", node);
8915
8916     list = (void*)0xdeadbeef;
8917     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8918     ok(hr == S_OK, "got 0x%08x\n", hr);
8919     len = 1;
8920     hr = IXMLDOMNodeList_get_length(list, &len);
8921     ok(hr == S_OK, "got 0x%08x\n", hr);
8922     ok(len == 0, "got %d\n", len);
8923     IXMLDOMNodeList_Release(list);
8924
8925     IXMLDOMDocument_Release(doc);
8926     free_bstrs();
8927 }
8928
8929 static void test_events(void)
8930 {
8931     IConnectionPointContainer *conn;
8932     IConnectionPoint *point;
8933     IXMLDOMDocument *doc;
8934     HRESULT hr;
8935     VARIANT v;
8936     IDispatch *event;
8937
8938     doc = create_document(&IID_IXMLDOMDocument);
8939     if (!doc) return;
8940
8941     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8942     ok(hr == S_OK, "got 0x%08x\n", hr);
8943
8944     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8945     ok(hr == S_OK, "got 0x%08x\n", hr);
8946     IConnectionPoint_Release(point);
8947     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8948     ok(hr == S_OK, "got 0x%08x\n", hr);
8949     IConnectionPoint_Release(point);
8950     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8951     ok(hr == S_OK, "got 0x%08x\n", hr);
8952     IConnectionPoint_Release(point);
8953
8954     IConnectionPointContainer_Release(conn);
8955
8956     /* ready state callback */
8957     VariantInit(&v);
8958     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8959     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8960
8961     event = create_dispevent();
8962     V_VT(&v) = VT_UNKNOWN;
8963     V_UNKNOWN(&v) = (IUnknown*)event;
8964
8965     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8966     ok(hr == S_OK, "got 0x%08x\n", hr);
8967     EXPECT_REF(event, 2);
8968
8969     V_VT(&v) = VT_DISPATCH;
8970     V_DISPATCH(&v) = event;
8971
8972     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8973     ok(hr == S_OK, "got 0x%08x\n", hr);
8974     EXPECT_REF(event, 2);
8975
8976     /* VT_NULL doesn't reset event handler */
8977     V_VT(&v) = VT_NULL;
8978     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8979     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8980     EXPECT_REF(event, 2);
8981
8982     V_VT(&v) = VT_DISPATCH;
8983     V_DISPATCH(&v) = NULL;
8984
8985     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8986     ok(hr == S_OK, "got 0x%08x\n", hr);
8987     EXPECT_REF(event, 1);
8988
8989     V_VT(&v) = VT_UNKNOWN;
8990     V_DISPATCH(&v) = NULL;
8991     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8992     ok(hr == S_OK, "got 0x%08x\n", hr);
8993
8994     IDispatch_Release(event);
8995
8996     IXMLDOMDocument_Release(doc);
8997 }
8998
8999 static void test_createProcessingInstruction(void)
9000 {
9001     static const WCHAR bodyW[] = {'t','e','s','t',0};
9002     IXMLDOMProcessingInstruction *pi;
9003     IXMLDOMDocument *doc;
9004     WCHAR buff[10];
9005     HRESULT hr;
9006
9007     doc = create_document(&IID_IXMLDOMDocument);
9008     if (!doc) return;
9009
9010     /* test for BSTR handling, pass broken BSTR */
9011     memcpy(&buff[2], bodyW, sizeof(bodyW));
9012     /* just a big length */
9013     *(DWORD*)buff = 0xf0f0;
9014     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9015     ok(hr == S_OK, "got 0x%08x\n", hr);
9016
9017     IXMLDOMProcessingInstruction_Release(pi);
9018     IXMLDOMDocument_Release(doc);
9019 }
9020
9021 static void test_put_nodeTypedValue(void)
9022 {
9023     IXMLDOMDocument *doc;
9024     IXMLDOMElement *elem;
9025     VARIANT type;
9026     HRESULT hr;
9027
9028     doc = create_document(&IID_IXMLDOMDocument);
9029     if (!doc) return;
9030
9031     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9032     ok(hr == S_OK, "got 0x%08x\n", hr);
9033
9034     V_VT(&type) = VT_EMPTY;
9035     hr = IXMLDOMElement_get_dataType(elem, &type);
9036     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9037     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9038
9039     /* set typed value for untyped node */
9040     V_VT(&type) = VT_I1;
9041     V_I1(&type) = 1;
9042     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9043     ok(hr == S_OK, "got 0x%08x\n", hr);
9044
9045     V_VT(&type) = VT_EMPTY;
9046     hr = IXMLDOMElement_get_dataType(elem, &type);
9047     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9048     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9049
9050     /* no type info stored */
9051     V_VT(&type) = VT_EMPTY;
9052     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9053     ok(hr == S_OK, "got 0x%08x\n", hr);
9054     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9055     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9056        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9057     VariantClear(&type);
9058
9059     IXMLDOMElement_Release(elem);
9060     IXMLDOMDocument_Release(doc);
9061     free_bstrs();
9062 }
9063
9064 static void test_get_xml(void)
9065 {
9066     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9067     static const char fooA[] = "<foo/>";
9068     IXMLDOMProcessingInstruction *pi;
9069     IXMLDOMNode *first;
9070     IXMLDOMElement *elem = NULL;
9071     IXMLDOMDocument *doc;
9072     VARIANT_BOOL b;
9073     VARIANT v;
9074     BSTR xml;
9075     HRESULT hr;
9076
9077     doc = create_document(&IID_IXMLDOMDocument);
9078     if (!doc) return;
9079
9080     b = VARIANT_TRUE;
9081     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9082     ok(hr == S_OK, "got 0x%08x\n", hr);
9083     ok( b == VARIANT_TRUE, "got %d\n", b);
9084
9085     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9086                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9087     ok(hr == S_OK, "got 0x%08x\n", hr);
9088
9089     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9090     ok(hr == S_OK, "got 0x%08x\n", hr);
9091
9092     V_UNKNOWN(&v) = (IUnknown*)first;
9093     V_VT(&v) = VT_UNKNOWN;
9094
9095     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9096     ok(hr == S_OK, "got 0x%08x\n", hr);
9097
9098     IXMLDOMProcessingInstruction_Release(pi);
9099     IXMLDOMNode_Release(first);
9100
9101     hr = IXMLDOMDocument_get_xml(doc, &xml);
9102     ok(hr == S_OK, "got 0x%08x\n", hr);
9103
9104     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9105         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9106     SysFreeString(xml);
9107
9108     IXMLDOMDocument_Release(doc);
9109
9110     doc = create_document(&IID_IXMLDOMDocument);
9111
9112     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9113     ok(hr == S_OK, "got 0x%08x\n", hr);
9114
9115     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9116     ok(hr == S_OK, "got 0x%08x\n", hr);
9117
9118     hr = IXMLDOMDocument_get_xml(doc, &xml);
9119     ok(hr == S_OK, "got 0x%08x\n", hr);
9120
9121     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9122         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9123     SysFreeString(xml);
9124
9125     IXMLDOMElement_Release(elem);
9126     IXMLDOMDocument_Release(doc);
9127
9128     free_bstrs();
9129 }
9130
9131 static void test_xsltemplate(void)
9132 {
9133     IXSLTemplate *template;
9134     IXSLProcessor *processor;
9135     IXMLDOMDocument *doc, *doc2;
9136     IStream *stream;
9137     VARIANT_BOOL b;
9138     HRESULT hr;
9139     ULONG ref1, ref2;
9140     VARIANT v;
9141
9142     template = create_xsltemplate(&IID_IXSLTemplate);
9143     if (!template) return;
9144
9145     /* works as reset */
9146     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9147     ok(hr == S_OK, "got 0x%08x\n", hr);
9148
9149     doc = create_document(&IID_IXMLDOMDocument);
9150
9151     b = VARIANT_TRUE;
9152     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9153     ok(hr == S_OK, "got 0x%08x\n", hr);
9154     ok( b == VARIANT_TRUE, "got %d\n", b);
9155
9156     /* putref with non-xsl document */
9157     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9158     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9159
9160     b = VARIANT_TRUE;
9161     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9162     ok(hr == S_OK, "got 0x%08x\n", hr);
9163     ok( b == VARIANT_TRUE, "got %d\n", b);
9164
9165     /* not a freethreaded document */
9166     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9167     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9168
9169     IXMLDOMDocument_Release(doc);
9170
9171     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9172     if (hr != S_OK)
9173     {
9174         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9175         IXSLTemplate_Release(template);
9176         return;
9177     }
9178
9179     b = VARIANT_TRUE;
9180     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9181     ok(hr == S_OK, "got 0x%08x\n", hr);
9182     ok( b == VARIANT_TRUE, "got %d\n", b);
9183
9184     /* freethreaded document */
9185     ref1 = IXMLDOMDocument_AddRef(doc);
9186     IXMLDOMDocument_Release(doc);
9187     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9188     ok(hr == S_OK, "got 0x%08x\n", hr);
9189     ref2 = IXMLDOMDocument_AddRef(doc);
9190     IXMLDOMDocument_Release(doc);
9191     ok(ref2 > ref1, "got %d\n", ref2);
9192
9193     /* processor */
9194     hr = IXSLTemplate_createProcessor(template, NULL);
9195     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9196
9197     EXPECT_REF(template, 1);
9198     hr = IXSLTemplate_createProcessor(template, &processor);
9199     ok(hr == S_OK, "got 0x%08x\n", hr);
9200     EXPECT_REF(template, 2);
9201
9202     /* input no set yet */
9203     V_VT(&v) = VT_BSTR;
9204     V_BSTR(&v) = NULL;
9205     hr = IXSLProcessor_get_input(processor, &v);
9206 todo_wine {
9207     ok(hr == S_OK, "got 0x%08x\n", hr);
9208     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9209 }
9210
9211     hr = IXSLProcessor_get_output(processor, NULL);
9212     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9213
9214     /* reset before it was set */
9215     V_VT(&v) = VT_EMPTY;
9216     hr = IXSLProcessor_put_output(processor, v);
9217     ok(hr == S_OK, "got 0x%08x\n", hr);
9218
9219     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9220     EXPECT_REF(stream, 1);
9221
9222     V_VT(&v) = VT_UNKNOWN;
9223     V_UNKNOWN(&v) = (IUnknown*)stream;
9224     hr = IXSLProcessor_put_output(processor, v);
9225     ok(hr == S_OK, "got 0x%08x\n", hr);
9226
9227     /* it seems processor grabs 2 references */
9228     todo_wine EXPECT_REF(stream, 3);
9229
9230     V_VT(&v) = VT_EMPTY;
9231     hr = IXSLProcessor_get_output(processor, &v);
9232     ok(hr == S_OK, "got 0x%08x\n", hr);
9233     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9234     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9235
9236     todo_wine EXPECT_REF(stream, 4);
9237     VariantClear(&v);
9238
9239     hr = IXSLProcessor_transform(processor, NULL);
9240     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9241
9242     /* reset and check stream refcount */
9243     V_VT(&v) = VT_EMPTY;
9244     hr = IXSLProcessor_put_output(processor, v);
9245     ok(hr == S_OK, "got 0x%08x\n", hr);
9246
9247     EXPECT_REF(stream, 1);
9248
9249     IStream_Release(stream);
9250
9251     /* no output interface set, check output */
9252     doc2 = create_document(&IID_IXMLDOMDocument);
9253
9254     b = VARIANT_TRUE;
9255     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9256     ok(hr == S_OK, "got 0x%08x\n", hr);
9257     ok( b == VARIANT_TRUE, "got %d\n", b);
9258
9259     V_VT(&v) = VT_UNKNOWN;
9260     V_UNKNOWN(&v) = (IUnknown*)doc2;
9261     hr = IXSLProcessor_put_input(processor, v);
9262     ok(hr == S_OK, "got 0x%08x\n", hr);
9263
9264     hr = IXSLProcessor_transform(processor, &b);
9265     ok(hr == S_OK, "got 0x%08x\n", hr);
9266
9267     V_VT(&v) = VT_EMPTY;
9268     hr = IXSLProcessor_get_output(processor, &v);
9269     ok(hr == S_OK, "got 0x%08x\n", hr);
9270     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9271     /* we currently output one '\n' instead of empty string */
9272     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9273     IXMLDOMDocument_Release(doc2);
9274     VariantClear(&v);
9275
9276     IXSLProcessor_Release(processor);
9277
9278     /* drop reference */
9279     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9280     ok(hr == S_OK, "got 0x%08x\n", hr);
9281     ref2 = IXMLDOMDocument_AddRef(doc);
9282     IXMLDOMDocument_Release(doc);
9283     ok(ref2 == ref1, "got %d\n", ref2);
9284
9285     IXMLDOMDocument_Release(doc);
9286     IXSLTemplate_Release(template);
9287     free_bstrs();
9288 }
9289
9290 static void test_insertBefore(void)
9291 {
9292     IXMLDOMDocument *doc, *doc2;
9293     IXMLDOMAttribute *attr;
9294     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9295     IXMLDOMNode *node, *newnode;
9296     HRESULT hr;
9297     VARIANT v;
9298     BSTR p;
9299
9300     doc = create_document(&IID_IXMLDOMDocument);
9301
9302     /* insertBefore behaviour for attribute node */
9303     V_VT(&v) = VT_I4;
9304     V_I4(&v) = NODE_ATTRIBUTE;
9305
9306     attr = NULL;
9307     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9308     ok(hr == S_OK, "got 0x%08x\n", hr);
9309     ok(attr != NULL, "got %p\n", attr);
9310
9311     /* attribute to attribute */
9312     V_VT(&v) = VT_I4;
9313     V_I4(&v) = NODE_ATTRIBUTE;
9314     newnode = NULL;
9315     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9316     ok(hr == S_OK, "got 0x%08x\n", hr);
9317     ok(newnode != NULL, "got %p\n", newnode);
9318
9319     V_VT(&v) = VT_NULL;
9320     node = (void*)0xdeadbeef;
9321     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9322     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9323     ok(node == NULL, "got %p\n", node);
9324
9325     V_VT(&v) = VT_UNKNOWN;
9326     V_UNKNOWN(&v) = (IUnknown*)attr;
9327     node = (void*)0xdeadbeef;
9328     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9329     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9330     ok(node == NULL, "got %p\n", node);
9331     IXMLDOMNode_Release(newnode);
9332
9333     /* cdata to attribute */
9334     V_VT(&v) = VT_I4;
9335     V_I4(&v) = NODE_CDATA_SECTION;
9336     newnode = NULL;
9337     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9338     ok(hr == S_OK, "got 0x%08x\n", hr);
9339     ok(newnode != NULL, "got %p\n", newnode);
9340
9341     V_VT(&v) = VT_NULL;
9342     node = (void*)0xdeadbeef;
9343     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9344     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9345     ok(node == NULL, "got %p\n", node);
9346     IXMLDOMNode_Release(newnode);
9347
9348     /* comment to attribute */
9349     V_VT(&v) = VT_I4;
9350     V_I4(&v) = NODE_COMMENT;
9351     newnode = NULL;
9352     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9353     ok(hr == S_OK, "got 0x%08x\n", hr);
9354     ok(newnode != NULL, "got %p\n", newnode);
9355
9356     V_VT(&v) = VT_NULL;
9357     node = (void*)0xdeadbeef;
9358     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9359     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9360     ok(node == NULL, "got %p\n", node);
9361     IXMLDOMNode_Release(newnode);
9362
9363     /* element to attribute */
9364     V_VT(&v) = VT_I4;
9365     V_I4(&v) = NODE_ELEMENT;
9366     newnode = NULL;
9367     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9368     ok(hr == S_OK, "got 0x%08x\n", hr);
9369     ok(newnode != NULL, "got %p\n", newnode);
9370
9371     V_VT(&v) = VT_NULL;
9372     node = (void*)0xdeadbeef;
9373     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9374     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9375     ok(node == NULL, "got %p\n", node);
9376     IXMLDOMNode_Release(newnode);
9377
9378     /* pi to attribute */
9379     V_VT(&v) = VT_I4;
9380     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9381     newnode = NULL;
9382     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9383     ok(hr == S_OK, "got 0x%08x\n", hr);
9384     ok(newnode != NULL, "got %p\n", newnode);
9385
9386     V_VT(&v) = VT_NULL;
9387     node = (void*)0xdeadbeef;
9388     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9389     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9390     ok(node == NULL, "got %p\n", node);
9391     IXMLDOMNode_Release(newnode);
9392     IXMLDOMAttribute_Release(attr);
9393
9394     /* insertBefore for elements */
9395     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9396     ok(hr == S_OK, "got 0x%08x\n", hr);
9397
9398     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9399     ok(hr == S_OK, "got 0x%08x\n", hr);
9400
9401     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9402     ok(hr == S_OK, "got 0x%08x\n", hr);
9403
9404     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9405     ok(hr == S_OK, "got 0x%08x\n", hr);
9406
9407     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9408     ok(hr == S_OK, "got 0x%08x\n", hr);
9409
9410     EXPECT_NO_CHILDREN(elem1);
9411     EXPECT_NO_CHILDREN(elem2);
9412     EXPECT_NO_CHILDREN(elem3);
9413
9414     todo_wine EXPECT_REF(elem2, 2);
9415
9416     V_VT(&v) = VT_DISPATCH;
9417     V_DISPATCH(&v) = NULL;
9418     node = NULL;
9419     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9420     ok(hr == S_OK, "got 0x%08x\n", hr);
9421     ok(node == (void*)elem4, "got %p\n", node);
9422
9423     EXPECT_CHILDREN(elem1);
9424     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9425     EXPECT_HR(hr, S_OK);
9426     IXMLDOMElement_Release(elem4);
9427
9428     EXPECT_NO_CHILDREN(elem1);
9429
9430     V_VT(&v) = VT_NULL;
9431     node = NULL;
9432     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9433     ok(hr == S_OK, "got 0x%08x\n", hr);
9434     ok(node == (void*)elem2, "got %p\n", node);
9435
9436     EXPECT_CHILDREN(elem1);
9437     todo_wine EXPECT_REF(elem2, 3);
9438     IXMLDOMNode_Release(node);
9439
9440     /* again for already linked node */
9441     V_VT(&v) = VT_NULL;
9442     node = NULL;
9443     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9444     ok(hr == S_OK, "got 0x%08x\n", hr);
9445     ok(node == (void*)elem2, "got %p\n", node);
9446
9447     EXPECT_CHILDREN(elem1);
9448
9449     /* increments each time */
9450     todo_wine EXPECT_REF(elem2, 3);
9451     IXMLDOMNode_Release(node);
9452
9453     /* try to add to another element */
9454     V_VT(&v) = VT_NULL;
9455     node = (void*)0xdeadbeef;
9456     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9457     ok(hr == S_OK, "got 0x%08x\n", hr);
9458     ok(node == (void*)elem2, "got %p\n", node);
9459
9460     EXPECT_CHILDREN(elem3);
9461     EXPECT_NO_CHILDREN(elem1);
9462
9463     IXMLDOMNode_Release(node);
9464
9465     /* cross document case - try to add as child to a node created with other doc */
9466     doc2 = create_document(&IID_IXMLDOMDocument);
9467
9468     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9469     ok(hr == S_OK, "got 0x%08x\n", hr);
9470     todo_wine EXPECT_REF(elem4, 2);
9471
9472     /* same name, another instance */
9473     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9474     ok(hr == S_OK, "got 0x%08x\n", hr);
9475     todo_wine EXPECT_REF(elem5, 2);
9476
9477     todo_wine EXPECT_REF(elem3, 2);
9478     V_VT(&v) = VT_NULL;
9479     node = NULL;
9480     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9481     ok(hr == S_OK, "got 0x%08x\n", hr);
9482     ok(node == (void*)elem4, "got %p\n", node);
9483     todo_wine EXPECT_REF(elem4, 3);
9484     todo_wine EXPECT_REF(elem3, 2);
9485     IXMLDOMNode_Release(node);
9486
9487     V_VT(&v) = VT_NULL;
9488     node = NULL;
9489     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9490     ok(hr == S_OK, "got 0x%08x\n", hr);
9491     ok(node == (void*)elem5, "got %p\n", node);
9492     todo_wine EXPECT_REF(elem4, 2);
9493     todo_wine EXPECT_REF(elem5, 3);
9494     IXMLDOMNode_Release(node);
9495
9496     IXMLDOMDocument_Release(doc2);
9497
9498     IXMLDOMElement_Release(elem1);
9499     IXMLDOMElement_Release(elem2);
9500     IXMLDOMElement_Release(elem3);
9501     IXMLDOMElement_Release(elem4);
9502     IXMLDOMElement_Release(elem5);
9503
9504     /* elements with same default namespace */
9505     V_VT(&v) = VT_I4;
9506     V_I4(&v) = NODE_ELEMENT;
9507     elem1 = NULL;
9508     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9509     ok(hr == S_OK, "got 0x%08x\n", hr);
9510     ok(elem1 != NULL, "got %p\n", elem1);
9511
9512     V_VT(&v) = VT_I4;
9513     V_I4(&v) = NODE_ELEMENT;
9514     elem2 = NULL;
9515     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9516     ok(hr == S_OK, "got 0x%08x\n", hr);
9517     ok(elem2 != NULL, "got %p\n", elem2);
9518
9519     /* check contents so far */
9520     p = NULL;
9521     hr = IXMLDOMElement_get_xml(elem1, &p);
9522     ok(hr == S_OK, "got 0x%08x\n", hr);
9523     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9524     SysFreeString(p);
9525
9526     p = NULL;
9527     hr = IXMLDOMElement_get_xml(elem2, &p);
9528     ok(hr == S_OK, "got 0x%08x\n", hr);
9529     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9530     SysFreeString(p);
9531
9532     V_VT(&v) = VT_NULL;
9533     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9534     ok(hr == S_OK, "got 0x%08x\n", hr);
9535
9536     /* get_xml depends on context, for top node it omits child namespace attribute,
9537        but at child level it's still returned */
9538     p = NULL;
9539     hr = IXMLDOMElement_get_xml(elem1, &p);
9540     ok(hr == S_OK, "got 0x%08x\n", hr);
9541     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9542         "got %s\n", wine_dbgstr_w(p));
9543     SysFreeString(p);
9544
9545     p = NULL;
9546     hr = IXMLDOMElement_get_xml(elem2, &p);
9547     ok(hr == S_OK, "got 0x%08x\n", hr);
9548     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9549     SysFreeString(p);
9550
9551     IXMLDOMElement_Release(elem1);
9552     IXMLDOMElement_Release(elem2);
9553
9554     /* child without default namespace added to node with 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"), NULL, (IXMLDOMNode**)&elem2);
9566     ok(hr == S_OK, "got 0x%08x\n", hr);
9567     ok(elem2 != NULL, "got %p\n", elem2);
9568
9569     EXPECT_REF(elem2, 1);
9570     V_VT(&v) = VT_NULL;
9571     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9572     ok(hr == S_OK, "got 0x%08x\n", hr);
9573     EXPECT_REF(elem2, 1);
9574
9575     p = NULL;
9576     hr = IXMLDOMElement_get_xml(elem2, &p);
9577     ok(hr == S_OK, "got 0x%08x\n", hr);
9578     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9579     SysFreeString(p);
9580
9581     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9582     ok(hr == S_OK, "got 0x%08x\n", hr);
9583
9584     p = NULL;
9585     hr = IXMLDOMElement_get_xml(elem2, &p);
9586     ok(hr == S_OK, "got 0x%08x\n", hr);
9587     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9588     SysFreeString(p);
9589
9590     IXMLDOMElement_Release(elem1);
9591     IXMLDOMElement_Release(elem2);
9592     IXMLDOMDocument_Release(doc);
9593 }
9594
9595 static void test_appendChild(void)
9596 {
9597     IXMLDOMDocument *doc, *doc2;
9598     IXMLDOMElement *elem, *elem2;
9599     HRESULT hr;
9600
9601     doc = create_document(&IID_IXMLDOMDocument);
9602     doc2 = create_document(&IID_IXMLDOMDocument);
9603
9604     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9605     ok(hr == S_OK, "got 0x%08x\n", hr);
9606
9607     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9608     ok(hr == S_OK, "got 0x%08x\n", hr);
9609
9610     EXPECT_REF(doc, 1);
9611     todo_wine EXPECT_REF(elem, 2);
9612     EXPECT_REF(doc2, 1);
9613     todo_wine EXPECT_REF(elem2, 2);
9614     EXPECT_NO_CHILDREN(doc);
9615     EXPECT_NO_CHILDREN(doc2);
9616
9617     /* append from another document */
9618     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9619     ok(hr == S_OK, "got 0x%08x\n", hr);
9620
9621     EXPECT_REF(doc, 1);
9622     todo_wine EXPECT_REF(elem, 2);
9623     EXPECT_REF(doc2, 1);
9624     todo_wine EXPECT_REF(elem2, 2);
9625     EXPECT_NO_CHILDREN(doc);
9626     EXPECT_CHILDREN(doc2);
9627
9628     IXMLDOMElement_Release(elem);
9629     IXMLDOMElement_Release(elem2);
9630     IXMLDOMDocument_Release(doc);
9631     IXMLDOMDocument_Release(doc2);
9632 }
9633
9634 static void test_get_doctype(void)
9635 {
9636     IXMLDOMDocumentType *doctype;
9637     IXMLDOMDocument *doc;
9638     HRESULT hr;
9639
9640     doc = create_document(&IID_IXMLDOMDocument);
9641
9642     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9643     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9644
9645     doctype = (void*)0xdeadbeef;
9646     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9647     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9648     ok(doctype == NULL, "got %p\n", doctype);
9649
9650     IXMLDOMDocument_Release(doc);
9651 }
9652
9653 static void test_get_tagName(void)
9654 {
9655     IXMLDOMDocument *doc;
9656     IXMLDOMElement *elem, *elem2;
9657     HRESULT hr;
9658     BSTR str;
9659
9660     doc = create_document(&IID_IXMLDOMDocument);
9661
9662     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9663     ok(hr == S_OK, "got 0x%08x\n", hr);
9664
9665     hr = IXMLDOMElement_get_tagName(elem, NULL);
9666     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9667
9668     str = NULL;
9669     hr = IXMLDOMElement_get_tagName(elem, &str);
9670     ok(hr == S_OK, "got 0x%08x\n", hr);
9671     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9672     SysFreeString(str);
9673
9674     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9675     ok(hr == S_OK, "got 0x%08x\n", hr);
9676
9677     str = NULL;
9678     hr = IXMLDOMElement_get_tagName(elem2, &str);
9679     ok(hr == S_OK, "got 0x%08x\n", hr);
9680     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9681     SysFreeString(str);
9682
9683     IXMLDOMDocument_Release(elem);
9684     IXMLDOMDocument_Release(elem2);
9685     IXMLDOMDocument_Release(doc);
9686     free_bstrs();
9687 }
9688
9689 typedef struct {
9690     DOMNodeType type;
9691     const char *name;
9692     VARTYPE vt;
9693     HRESULT hr;
9694 } node_type_t;
9695
9696 static const node_type_t get_datatype[] = {
9697     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9698     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9699     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9700     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9701     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9702     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9703     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9704     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9705     { 0 }
9706 };
9707
9708 static void test_get_dataType(void)
9709 {
9710     const node_type_t *entry = get_datatype;
9711     IXMLDOMDocument *doc;
9712
9713     doc = create_document(&IID_IXMLDOMDocument);
9714
9715     while (entry->type)
9716     {
9717         IXMLDOMNode *node = NULL;
9718         VARIANT var, type;
9719         HRESULT hr;
9720
9721         V_VT(&var) = VT_I4;
9722         V_I4(&var) = entry->type;
9723         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9724         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9725
9726         hr = IXMLDOMNode_get_dataType(node, NULL);
9727         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9728
9729         VariantInit(&type);
9730         hr = IXMLDOMNode_get_dataType(node, &type);
9731         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9732             hr, entry->hr, entry->type);
9733         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9734             V_VT(&type), entry->vt, entry->type);
9735         VariantClear(&type);
9736
9737         IXMLDOMNode_Release(node);
9738
9739         entry++;
9740     }
9741
9742     IXMLDOMDocument_Release(doc);
9743     free_bstrs();
9744 }
9745
9746 typedef struct _get_node_typestring_t {
9747     DOMNodeType type;
9748     const char *string;
9749 } get_node_typestring_t;
9750
9751 static const get_node_typestring_t get_node_typestring[] = {
9752     { NODE_ELEMENT,                "element"               },
9753     { NODE_ATTRIBUTE,              "attribute"             },
9754     { NODE_TEXT,                   "text"                  },
9755     { NODE_CDATA_SECTION ,         "cdatasection"          },
9756     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9757     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9758     { NODE_COMMENT,                "comment"               },
9759     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9760     { 0 }
9761 };
9762
9763 static void test_get_nodeTypeString(void)
9764 {
9765     const get_node_typestring_t *entry = get_node_typestring;
9766     IXMLDOMDocument *doc;
9767     HRESULT hr;
9768     BSTR str;
9769
9770     doc = create_document(&IID_IXMLDOMDocument);
9771
9772     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9773     ok(hr == S_OK, "got 0x%08x\n", hr);
9774     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9775     SysFreeString(str);
9776
9777     while (entry->type)
9778     {
9779         IXMLDOMNode *node = NULL;
9780         VARIANT var;
9781
9782         V_VT(&var) = VT_I4;
9783         V_I4(&var) = entry->type;
9784         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9785         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9786
9787         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9788         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9789
9790         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9791         ok(hr == S_OK, "got 0x%08x\n", hr);
9792         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9793             wine_dbgstr_w(str), entry->string, entry->type);
9794         SysFreeString(str);
9795         IXMLDOMNode_Release(node);
9796
9797         entry++;
9798     }
9799
9800     IXMLDOMDocument_Release(doc);
9801     free_bstrs();
9802 }
9803
9804 typedef struct _get_attributes_t {
9805     DOMNodeType type;
9806     HRESULT hr;
9807 } get_attributes_t;
9808
9809 static const get_attributes_t get_attributes[] = {
9810     { NODE_ATTRIBUTE,              S_FALSE },
9811     { NODE_TEXT,                   S_FALSE },
9812     { NODE_CDATA_SECTION ,         S_FALSE },
9813     { NODE_ENTITY_REFERENCE,       S_FALSE },
9814     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9815     { NODE_COMMENT,                S_FALSE },
9816     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9817     { 0 }
9818 };
9819
9820 static void test_get_attributes(void)
9821 {
9822     const get_attributes_t *entry = get_attributes;
9823     IXMLDOMNamedNodeMap *map;
9824     IXMLDOMDocument *doc;
9825     IXMLDOMNode *node, *node2;
9826     VARIANT_BOOL b;
9827     HRESULT hr;
9828     BSTR str;
9829     LONG length;
9830
9831     doc = create_document(&IID_IXMLDOMDocument);
9832
9833     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9834     ok(hr == S_OK, "got %08x\n", hr);
9835
9836     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9837     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9838
9839     map = (void*)0xdeadbeef;
9840     hr = IXMLDOMDocument_get_attributes(doc, &map);
9841     ok(hr == S_FALSE, "got %08x\n", hr);
9842     ok(map == NULL, "got %p\n", map);
9843
9844     /* first child is <?xml ?> */
9845     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9846     ok(hr == S_OK, "got %08x\n", hr);
9847
9848     hr = IXMLDOMNode_get_attributes(node, &map);
9849     ok(hr == S_OK, "got %08x\n", hr);
9850
9851     length = -1;
9852     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9853     EXPECT_HR(hr, S_OK);
9854     todo_wine ok(length == 1, "got %d\n", length);
9855
9856     if (hr == S_OK && length == 1)
9857     {
9858         IXMLDOMAttribute *attr;
9859         DOMNodeType type;
9860         VARIANT v;
9861
9862         node2 = NULL;
9863         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9864         EXPECT_HR(hr, S_OK);
9865         ok(node != NULL, "got %p\n", node2);
9866
9867         hr = IXMLDOMNode_get_nodeName(node2, &str);
9868         EXPECT_HR(hr, S_OK);
9869         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9870         SysFreeString(str);
9871
9872         length = -1;
9873         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9874         EXPECT_HR(hr, S_OK);
9875         ok(length == 1, "got %d\n", length);
9876
9877         type = -1;
9878         hr = IXMLDOMNode_get_nodeType(node2, &type);
9879         EXPECT_HR(hr, S_OK);
9880         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9881
9882         hr = IXMLDOMNode_get_xml(node, &str);
9883         EXPECT_HR(hr, S_OK);
9884         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9885         SysFreeString(str);
9886
9887         hr = IXMLDOMNode_get_text(node, &str);
9888         EXPECT_HR(hr, S_OK);
9889         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9890         SysFreeString(str);
9891
9892         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9893         EXPECT_HR(hr, S_OK);
9894
9895         length = -1;
9896         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9897         EXPECT_HR(hr, S_OK);
9898         ok(length == 0, "got %d\n", length);
9899
9900         hr = IXMLDOMNode_get_xml(node, &str);
9901         EXPECT_HR(hr, S_OK);
9902         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9903         SysFreeString(str);
9904
9905         hr = IXMLDOMNode_get_text(node, &str);
9906         EXPECT_HR(hr, S_OK);
9907         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9908         SysFreeString(str);
9909
9910         IXMLDOMNamedNodeMap_Release(map);
9911
9912         hr = IXMLDOMNode_get_attributes(node, &map);
9913         ok(hr == S_OK, "got %08x\n", hr);
9914
9915         length = -1;
9916         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9917         EXPECT_HR(hr, S_OK);
9918         ok(length == 0, "got %d\n", length);
9919
9920         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9921         EXPECT_HR(hr, S_OK);
9922
9923         V_VT(&v) = VT_BSTR;
9924         V_BSTR(&v) = _bstr_("UTF-8");
9925         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9926         EXPECT_HR(hr, S_OK);
9927
9928         EXPECT_REF(attr, 2);
9929         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9930         EXPECT_HR(hr, S_OK);
9931         EXPECT_REF(attr, 2);
9932
9933         hr = IXMLDOMNode_get_attributes(node, &map);
9934         ok(hr == S_OK, "got %08x\n", hr);
9935
9936         length = -1;
9937         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9938         EXPECT_HR(hr, S_OK);
9939         ok(length == 1, "got %d\n", length);
9940
9941         hr = IXMLDOMNode_get_xml(node, &str);
9942         EXPECT_HR(hr, S_OK);
9943         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9944         SysFreeString(str);
9945
9946         hr = IXMLDOMNode_get_text(node, &str);
9947         EXPECT_HR(hr, S_OK);
9948         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9949         SysFreeString(str);
9950
9951         IXMLDOMNamedNodeMap_Release(map);
9952         IXMLDOMNode_Release(node2);
9953     }
9954
9955     IXMLDOMNode_Release(node);
9956
9957     /* last child is element */
9958     EXPECT_REF(doc, 1);
9959     hr = IXMLDOMDocument_get_lastChild(doc, &node);
9960     ok(hr == S_OK, "got %08x\n", hr);
9961     EXPECT_REF(doc, 1);
9962
9963     EXPECT_REF(node, 1);
9964     hr = IXMLDOMNode_get_attributes(node, &map);
9965     ok(hr == S_OK, "got %08x\n", hr);
9966     EXPECT_REF(node, 1);
9967     EXPECT_REF(doc, 1);
9968
9969     EXPECT_REF(map, 1);
9970     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9971     ok(hr == S_OK, "got %08x\n", hr);
9972     EXPECT_REF(node, 1);
9973     EXPECT_REF(node2, 1);
9974     EXPECT_REF(map, 1);
9975     EXPECT_REF(doc, 1);
9976     IXMLDOMNode_Release(node2);
9977
9978     /* release node before map release, map still works */
9979     IXMLDOMNode_Release(node);
9980
9981     length = 0;
9982     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9983     ok(hr == S_OK, "got %08x\n", hr);
9984     ok(length == 1, "got %d\n", length);
9985
9986     node2 = NULL;
9987     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9988     ok(hr == S_OK, "got %08x\n", hr);
9989     EXPECT_REF(node2, 1);
9990     IXMLDOMNode_Release(node2);
9991
9992     IXMLDOMNamedNodeMap_Release(map);
9993
9994     while (entry->type)
9995     {
9996         VARIANT var;
9997
9998         node = NULL;
9999
10000         V_VT(&var) = VT_I4;
10001         V_I4(&var) = entry->type;
10002         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10003         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10004
10005         hr = IXMLDOMNode_get_attributes(node, NULL);
10006         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10007
10008         map = (void*)0xdeadbeef;
10009         hr = IXMLDOMNode_get_attributes(node, &map);
10010         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10011             hr, entry->hr, entry->type);
10012         ok(map == NULL, "got %p\n", map);
10013
10014         IXMLDOMNode_Release(node);
10015
10016         entry++;
10017     }
10018
10019     IXMLDOMDocument_Release(doc);
10020     free_bstrs();
10021 }
10022
10023 static void test_selection(void)
10024 {
10025     IXMLDOMSelection *selection, *selection2;
10026     IEnumVARIANT *enum1, *enum2, *enum3;
10027     IXMLDOMNodeList *list;
10028     IXMLDOMDocument *doc;
10029     IDispatchEx *dispex;
10030     IXMLDOMNode *node;
10031     IDispatch *disp;
10032     VARIANT_BOOL b;
10033     HRESULT hr;
10034     DISPID did;
10035     VARIANT v;
10036     BSTR name;
10037     ULONG ret;
10038     LONG len;
10039
10040     doc = create_document(&IID_IXMLDOMDocument);
10041
10042     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
10043     EXPECT_HR(hr, S_OK);
10044
10045     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10046     EXPECT_HR(hr, S_OK);
10047
10048     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10049     EXPECT_HR(hr, S_OK);
10050     IXMLDOMSelection_Release(selection);
10051
10052     /* collection disp id */
10053     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10054     EXPECT_HR(hr, S_OK);
10055     did = 0;
10056     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10057     EXPECT_HR(hr, S_OK);
10058     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10059     len = 0;
10060     hr = IXMLDOMSelection_get_length(selection, &len);
10061     EXPECT_HR(hr, S_OK);
10062     ok(len == 1, "got %d\n", len);
10063     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10064     EXPECT_HR(hr, S_OK);
10065     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10066     IDispatchEx_Release(dispex);
10067
10068     /* IEnumVARIANT tests */
10069     enum1 = NULL;
10070     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10071     EXPECT_HR(hr, S_OK);
10072     ok(enum1 != NULL, "got %p\n", enum1);
10073     EXPECT_REF(enum1, 2);
10074
10075     enum3 = NULL;
10076     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10077     EXPECT_HR(hr, S_OK);
10078     ok(enum3 != NULL, "got %p\n", enum3);
10079     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10080     EXPECT_REF(enum1, 3);
10081     IEnumVARIANT_Release(enum3);
10082
10083     EXPECT_REF(selection, 1);
10084     EXPECT_REF(enum1, 2);
10085
10086     enum2 = NULL;
10087     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10088     EXPECT_HR(hr, S_OK);
10089     ok(enum2 != NULL, "got %p\n", enum2);
10090
10091     EXPECT_REF(selection, 2);
10092     EXPECT_REF(enum1, 2);
10093     EXPECT_REF(enum2, 1);
10094
10095     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10096
10097     selection2 = NULL;
10098     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10099     EXPECT_HR(hr, S_OK);
10100     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10101     EXPECT_REF(selection, 3);
10102     EXPECT_REF(enum1, 2);
10103
10104     IXMLDOMSelection_Release(selection2);
10105
10106     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10107     EXPECT_HR(hr, S_OK);
10108     EXPECT_REF(selection, 3);
10109     IDispatch_Release(disp);
10110
10111     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10112     EXPECT_HR(hr, S_OK);
10113     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10114     EXPECT_REF(selection, 2);
10115     EXPECT_REF(enum1, 3);
10116
10117     IEnumVARIANT_Release(enum1);
10118     IEnumVARIANT_Release(enum2);
10119
10120     enum1 = NULL;
10121     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10122     EXPECT_HR(hr, S_OK);
10123     ok(enum1 != NULL, "got %p\n", enum1);
10124     EXPECT_REF(enum1, 1);
10125     EXPECT_REF(selection, 2);
10126
10127     enum2 = NULL;
10128     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10129     EXPECT_HR(hr, S_OK);
10130     ok(enum2 != NULL, "got %p\n", enum2);
10131     EXPECT_REF(enum2, 1);
10132     EXPECT_REF(selection, 3);
10133
10134     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10135
10136     IEnumVARIANT_AddRef(enum1);
10137     EXPECT_REF(selection, 3);
10138     EXPECT_REF(enum1, 2);
10139     EXPECT_REF(enum2, 1);
10140     IEnumVARIANT_Release(enum1);
10141
10142     IEnumVARIANT_Release(enum1);
10143     IEnumVARIANT_Release(enum2);
10144
10145     EXPECT_REF(selection, 1);
10146
10147     IXMLDOMNodeList_Release(list);
10148
10149     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10150     EXPECT_HR(hr, S_OK);
10151
10152     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10153     EXPECT_HR(hr, E_NOINTERFACE);
10154
10155     IXMLDOMNodeList_Release(list);
10156
10157     /* test if IEnumVARIANT touches selection context */
10158     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10159     EXPECT_HR(hr, S_OK);
10160
10161     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10162     EXPECT_HR(hr, S_OK);
10163
10164     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10165     EXPECT_HR(hr, S_OK);
10166
10167     len = 0;
10168     hr = IXMLDOMSelection_get_length(selection, &len);
10169     EXPECT_HR(hr, S_OK);
10170     ok(len == 4, "got %d\n", len);
10171
10172     enum1 = NULL;
10173     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10174     EXPECT_HR(hr, S_OK);
10175
10176     /* no-op if zero count */
10177     V_VT(&v) = VT_I2;
10178     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10179     EXPECT_HR(hr, S_OK);
10180     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10181
10182     /* positive count, null array pointer */
10183     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10184     EXPECT_HR(hr, E_INVALIDARG);
10185
10186     ret = 1;
10187     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10188     EXPECT_HR(hr, E_INVALIDARG);
10189     ok(ret == 0, "got %d\n", ret);
10190
10191     V_VT(&v) = VT_I2;
10192     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10193     EXPECT_HR(hr, S_OK);
10194     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10195
10196     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10197     EXPECT_HR(hr, S_OK);
10198     hr = IXMLDOMNode_get_nodeName(node, &name);
10199     EXPECT_HR(hr, S_OK);
10200     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10201     SysFreeString(name);
10202     IXMLDOMNode_Release(node);
10203     VariantClear(&v);
10204
10205     /* list cursor is updated */
10206     hr = IXMLDOMSelection_nextNode(selection, &node);
10207     EXPECT_HR(hr, S_OK);
10208     hr = IXMLDOMNode_get_nodeName(node, &name);
10209     EXPECT_HR(hr, S_OK);
10210     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10211     IXMLDOMNode_Release(node);
10212
10213     V_VT(&v) = VT_I2;
10214     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10215     EXPECT_HR(hr, S_OK);
10216     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10217     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10218     EXPECT_HR(hr, S_OK);
10219     hr = IXMLDOMNode_get_nodeName(node, &name);
10220     EXPECT_HR(hr, S_OK);
10221     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10222     SysFreeString(name);
10223     IXMLDOMNode_Release(node);
10224     VariantClear(&v);
10225
10226     hr = IXMLDOMSelection_nextNode(selection, &node);
10227     EXPECT_HR(hr, S_OK);
10228     hr = IXMLDOMNode_get_nodeName(node, &name);
10229     EXPECT_HR(hr, S_OK);
10230     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10231     IXMLDOMNode_Release(node);
10232
10233     IXMLDOMSelection_Release(selection);
10234     IXMLDOMNodeList_Release(list);
10235     IXMLDOMDocument_Release(doc);
10236
10237     free_bstrs();
10238 }
10239
10240 static void test_load(void)
10241 {
10242     IXMLDOMDocument *doc;
10243     IXMLDOMNodeList *list;
10244     VARIANT_BOOL b;
10245     HANDLE hfile;
10246     VARIANT src;
10247     HRESULT hr;
10248     BOOL ret;
10249     BSTR path, bstr1, bstr2;
10250     DWORD written;
10251     void* ptr;
10252
10253     /* prepare a file */
10254     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10255     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10256     if(hfile == INVALID_HANDLE_VALUE) return;
10257
10258     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10259     ok(ret, "WriteFile failed\n");
10260
10261     CloseHandle(hfile);
10262
10263     doc = create_document(&IID_IXMLDOMDocument);
10264
10265     path = _bstr_("test.xml");
10266
10267     /* load from path: VT_BSTR */
10268     V_VT(&src) = VT_BSTR;
10269     V_BSTR(&src) = path;
10270     hr = IXMLDOMDocument_load(doc, src, &b);
10271     EXPECT_HR(hr, S_OK);
10272     ok(b == VARIANT_TRUE, "got %d\n", b);
10273
10274     /* load from a path: VT_BSTR|VT_BYREF */
10275     V_VT(&src) = VT_BSTR | VT_BYREF;
10276     V_BSTRREF(&src) = &path;
10277     hr = IXMLDOMDocument_load(doc, src, &b);
10278     EXPECT_HR(hr, S_OK);
10279     ok(b == VARIANT_TRUE, "got %d\n", b);
10280
10281     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10282     V_VT(&src) = VT_BSTR | VT_BYREF;
10283     V_BSTRREF(&src) = NULL;
10284     hr = IXMLDOMDocument_load(doc, src, &b);
10285     EXPECT_HR(hr, E_INVALIDARG);
10286     ok(b == VARIANT_FALSE, "got %d\n", b);
10287
10288     IXMLDOMDocument_Release(doc);
10289
10290     DeleteFileA("test.xml");
10291
10292     doc = create_document(&IID_IXMLDOMDocument);
10293
10294     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10295     EXPECT_HR(hr, S_OK);
10296     ok(b == VARIANT_TRUE, "got %d\n", b);
10297
10298     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10299     EXPECT_HR(hr, S_OK);
10300     bstr1 = _bstr_(list_to_string(list));
10301
10302     hr = IXMLDOMNodeList_reset(list);
10303     EXPECT_HR(hr, S_OK);
10304
10305     IXMLDOMDocument_Release(doc);
10306
10307     doc = create_document(&IID_IXMLDOMDocument);
10308
10309     VariantInit(&src);
10310     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10311     V_VT(&src) = VT_ARRAY|VT_UI1;
10312     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10313     ptr = NULL;
10314     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10315     EXPECT_HR(hr, S_OK);
10316     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10317
10318     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10319     hr = SafeArrayUnlock(V_ARRAY(&src));
10320     EXPECT_HR(hr, S_OK);
10321
10322     hr = IXMLDOMDocument_load(doc, src, &b);
10323     EXPECT_HR(hr, S_OK);
10324     ok(b == VARIANT_TRUE, "got %d\n", b);
10325
10326     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10327     EXPECT_HR(hr, S_OK);
10328     bstr2 = _bstr_(list_to_string(list));
10329
10330     hr = IXMLDOMNodeList_reset(list);
10331     EXPECT_HR(hr, S_OK);
10332
10333     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10334        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10335
10336     IXMLDOMDocument_Release(doc);
10337     IXMLDOMNodeList_Release(list);
10338     VariantClear(&src);
10339
10340     /* UTF-16 isn't accepted */
10341     doc = create_document(&IID_IXMLDOMDocument);
10342
10343     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10344     V_VT(&src) = VT_ARRAY|VT_UI1;
10345     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10346     ptr = NULL;
10347     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10348     EXPECT_HR(hr, S_OK);
10349     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10350
10351     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10352     hr = SafeArrayUnlock(V_ARRAY(&src));
10353     EXPECT_HR(hr, S_OK);
10354
10355     hr = IXMLDOMDocument_load(doc, src, &b);
10356     todo_wine EXPECT_HR(hr, S_FALSE);
10357     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10358
10359     VariantClear(&src);
10360
10361     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10362     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10363     V_VT(&src) = VT_ARRAY|VT_UI2;
10364     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10365     ptr = NULL;
10366     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10367     EXPECT_HR(hr, S_OK);
10368     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10369
10370     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10371     hr = SafeArrayUnlock(V_ARRAY(&src));
10372     EXPECT_HR(hr, S_OK);
10373
10374     hr = IXMLDOMDocument_load(doc, src, &b);
10375     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10376     ok(b == VARIANT_FALSE, "got %d\n", b);
10377
10378     VariantClear(&src);
10379     IXMLDOMDocument_Release(doc);
10380
10381     free_bstrs();
10382 }
10383
10384 static void test_domobj_dispex(IUnknown *obj)
10385 {
10386     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10387     IDispatchEx *dispex;
10388     IUnknown *unk;
10389     DWORD props;
10390     UINT ticnt;
10391     HRESULT hr;
10392     BSTR name;
10393
10394     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10395     EXPECT_HR(hr, S_OK);
10396     if (FAILED(hr)) return;
10397
10398     ticnt = 0;
10399     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10400     EXPECT_HR(hr, S_OK);
10401     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10402
10403     name = SysAllocString(szstar);
10404     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10405     EXPECT_HR(hr, E_NOTIMPL);
10406     SysFreeString(name);
10407
10408     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10409     EXPECT_HR(hr, E_NOTIMPL);
10410
10411     props = 0;
10412     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10413     EXPECT_HR(hr, E_NOTIMPL);
10414     ok(props == 0, "expected 0 got %d\n", props);
10415
10416     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10417     EXPECT_HR(hr, E_NOTIMPL);
10418     if (SUCCEEDED(hr)) SysFreeString(name);
10419
10420     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10421     EXPECT_HR(hr, E_NOTIMPL);
10422
10423     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10424     EXPECT_HR(hr, E_NOTIMPL);
10425     if (hr == S_OK && unk) IUnknown_Release(unk);
10426
10427     IDispatchEx_Release(dispex);
10428 }
10429
10430 static void test_mxnamespacemanager(void)
10431 {
10432     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10433     IVBMXNamespaceManager *mgr2;
10434     IMXNamespaceManager *nsmgr;
10435     WCHAR buffW[250];
10436     IDispatch *disp;
10437     IUnknown *unk;
10438     HRESULT hr;
10439     INT len;
10440
10441     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10442         &IID_IMXNamespaceManager, (void**)&nsmgr);
10443     EXPECT_HR(hr, S_OK);
10444
10445     /* IMXNamespaceManager inherits from IUnknown */
10446     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10447     EXPECT_HR(hr, S_OK);
10448     IDispatch_Release(disp);
10449
10450     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10451     EXPECT_HR(hr, S_OK);
10452     IVBMXNamespaceManager_Release(mgr2);
10453
10454     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10455     EXPECT_HR(hr, S_OK);
10456
10457     /* prefix already added */
10458     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10459     EXPECT_HR(hr, S_FALSE);
10460
10461     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10462     EXPECT_HR(hr, E_INVALIDARG);
10463
10464     /* "xml" and "xmlns" are not allowed here */
10465     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10466     EXPECT_HR(hr, E_INVALIDARG);
10467
10468     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10469     EXPECT_HR(hr, E_INVALIDARG);
10470 todo_wine {
10471     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10472     EXPECT_HR(hr, E_FAIL);
10473 }
10474     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10475     EXPECT_HR(hr, E_POINTER);
10476
10477     len = -1;
10478     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10479     EXPECT_HR(hr, S_OK);
10480     ok(len == 3, "got %d\n", len);
10481
10482     len = -1;
10483     buffW[0] = 0x1;
10484     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10485     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10486     ok(len == -1, "got %d\n", len);
10487     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10488
10489     len = 10;
10490     buffW[0] = 0x1;
10491     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10492     EXPECT_HR(hr, S_OK);
10493     ok(len == 3, "got %d\n", len);
10494     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10495
10496     /* getURI */
10497     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10498     EXPECT_HR(hr, E_INVALIDARG);
10499
10500     len = -1;
10501     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10502     EXPECT_HR(hr, E_INVALIDARG);
10503     ok(len == -1, "got %d\n", len);
10504
10505     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10506     EXPECT_HR(hr, E_POINTER);
10507
10508     len = -1;
10509     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10510     EXPECT_HR(hr, S_OK);
10511     /* length of "xml" uri is constant */
10512     ok(len == strlen(xmluriA), "got %d\n", len);
10513
10514     len = 100;
10515     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10516     EXPECT_HR(hr, S_OK);
10517     ok(len == strlen(xmluriA), "got %d\n", len);
10518     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10519
10520     len = strlen(xmluriA)-1;
10521     buffW[0] = 0x1;
10522     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10523     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10524     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10525     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10526
10527     /* prefix xml1 not defined */
10528     len = -1;
10529     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10530     EXPECT_HR(hr, S_FALSE);
10531     ok(len == 0, "got %d\n", len);
10532
10533     len = 100;
10534     buffW[0] = 0x1;
10535     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10536     EXPECT_HR(hr, S_FALSE);
10537     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10538     ok(len == 0, "got %d\n", len);
10539
10540     /* IDispatchEx tests */
10541     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10542     EXPECT_HR(hr, S_OK);
10543     test_domobj_dispex(unk);
10544     IUnknown_Release(unk);
10545
10546     IMXNamespaceManager_Release(nsmgr);
10547
10548     /* ::getPrefix() */
10549     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10550         &IID_IMXNamespaceManager, (void**)&nsmgr);
10551     EXPECT_HR(hr, S_OK);
10552
10553     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10554     EXPECT_HR(hr, E_INVALIDARG);
10555
10556     len = -1;
10557     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10558     EXPECT_HR(hr, E_INVALIDARG);
10559     ok(len == -1, "got %d\n", len);
10560
10561     len = 100;
10562     buffW[0] = 0x1;
10563     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10564     EXPECT_HR(hr, E_FAIL);
10565     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10566     ok(len == 100, "got %d\n", len);
10567
10568     len = 0;
10569     buffW[0] = 0x1;
10570     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10571     EXPECT_HR(hr, E_FAIL);
10572     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10573     ok(len == 0, "got %d\n", len);
10574
10575     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10576     EXPECT_HR(hr, S_OK);
10577
10578     len = 100;
10579     buffW[0] = 0x1;
10580     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10581     EXPECT_HR(hr, S_OK);
10582     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10583     ok(len == 3, "got %d\n", len);
10584
10585     len = 100;
10586     buffW[0] = 0x1;
10587     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10588     EXPECT_HR(hr, S_OK);
10589     ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10590     ok(len == 3, "got %d\n", len);
10591
10592     /* with null buffer it's possible to get required length */
10593     len = 100;
10594     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10595     EXPECT_HR(hr, S_OK);
10596     ok(len == 3, "got %d\n", len);
10597
10598     len = 0;
10599     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10600     EXPECT_HR(hr, S_OK);
10601     ok(len == 3, "got %d\n", len);
10602
10603     len = 100;
10604     buffW[0] = 0x1;
10605     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10606     EXPECT_HR(hr, E_FAIL);
10607     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10608     ok(len == 100, "got %d\n", len);
10609
10610     len = 100;
10611     buffW[0] = 0x1;
10612     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10613     EXPECT_HR(hr, E_FAIL);
10614     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10615     ok(len == 100, "got %d\n", len);
10616
10617     len = 100;
10618     buffW[0] = 0x1;
10619     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10620     EXPECT_HR(hr, E_INVALIDARG);
10621     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10622     ok(len == 100, "got %d\n", len);
10623
10624     len = 100;
10625     buffW[0] = 0x1;
10626     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10627     EXPECT_HR(hr, E_INVALIDARG);
10628     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10629     ok(len == 100, "got %d\n", len);
10630
10631     len = 100;
10632     buffW[0] = 0x1;
10633     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10634     EXPECT_HR(hr, E_INVALIDARG);
10635     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10636     ok(len == 100, "got %d\n", len);
10637
10638     len = 100;
10639     buffW[0] = 0x1;
10640     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10641     EXPECT_HR(hr, E_FAIL);
10642     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10643     ok(len == 100, "got %d\n", len);
10644
10645     len = 100;
10646     buffW[0] = 0x1;
10647     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10648     EXPECT_HR(hr, E_INVALIDARG);
10649     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10650     ok(len == 100, "got %d\n", len);
10651
10652     /* declare another one, indices are shifted */
10653     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10654     EXPECT_HR(hr, S_OK);
10655
10656     len = 100;
10657     buffW[0] = 0x1;
10658     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10659     EXPECT_HR(hr, S_OK);
10660     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10661     ok(len == 3, "got %d\n", len);
10662
10663     len = 100;
10664     buffW[0] = 0x1;
10665     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10666     EXPECT_HR(hr, S_OK);
10667     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10668     ok(len == 3, "got %d\n", len);
10669
10670     len = 100;
10671     buffW[0] = 0x1;
10672     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10673     EXPECT_HR(hr, E_FAIL);
10674     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10675     ok(len == 100, "got %d\n", len);
10676
10677     len = 100;
10678     buffW[0] = 0x1;
10679     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10680     EXPECT_HR(hr, E_INVALIDARG);
10681     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10682     ok(len == 100, "got %d\n", len);
10683
10684     IMXNamespaceManager_Release(nsmgr);
10685
10686     free_bstrs();
10687 }
10688
10689 static void test_mxnamespacemanager_override(void)
10690 {
10691     IMXNamespaceManager *nsmgr;
10692     WCHAR buffW[250];
10693     VARIANT_BOOL b;
10694     HRESULT hr;
10695     INT len;
10696
10697     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10698         &IID_IMXNamespaceManager, (void**)&nsmgr);
10699     EXPECT_HR(hr, S_OK);
10700
10701     len = sizeof(buffW)/sizeof(WCHAR);
10702     buffW[0] = 0;
10703     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10704     EXPECT_HR(hr, S_OK);
10705     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10706
10707     len = sizeof(buffW)/sizeof(WCHAR);
10708     buffW[0] = 0;
10709     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10710     EXPECT_HR(hr, E_FAIL);
10711
10712     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10713     EXPECT_HR(hr, E_POINTER);
10714
10715     b = VARIANT_FALSE;
10716     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10717     EXPECT_HR(hr, S_OK);
10718     ok(b == VARIANT_TRUE, "got %d\n", b);
10719
10720     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10721     EXPECT_HR(hr, S_OK);
10722
10723     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10724     EXPECT_HR(hr, S_OK);
10725
10726     len = sizeof(buffW)/sizeof(WCHAR);
10727     buffW[0] = 0;
10728     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10729     EXPECT_HR(hr, S_OK);
10730     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10731
10732     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10733     EXPECT_HR(hr, S_OK);
10734
10735     len = sizeof(buffW)/sizeof(WCHAR);
10736     buffW[0] = 0;
10737     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10738     EXPECT_HR(hr, S_OK);
10739     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10740
10741     len = sizeof(buffW)/sizeof(WCHAR);
10742     buffW[0] = 0;
10743     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10744     EXPECT_HR(hr, S_OK);
10745     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10746
10747     len = sizeof(buffW)/sizeof(WCHAR);
10748     buffW[0] = 0;
10749     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10750     EXPECT_HR(hr, S_OK);
10751     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10752
10753     /* new prefix placed at index 1 always */
10754     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10755     EXPECT_HR(hr, S_OK);
10756
10757     len = sizeof(buffW)/sizeof(WCHAR);
10758     buffW[0] = 0;
10759     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10760     EXPECT_HR(hr, S_OK);
10761     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10762
10763     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10764     todo_wine EXPECT_HR(hr, E_FAIL);
10765
10766     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10767     EXPECT_HR(hr, E_FAIL);
10768
10769     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10770     EXPECT_HR(hr, E_FAIL);
10771
10772     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10773     EXPECT_HR(hr, S_OK);
10774
10775     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10776     EXPECT_HR(hr, S_FALSE);
10777
10778     len = sizeof(buffW)/sizeof(WCHAR);
10779     buffW[0] = 0;
10780     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10781     EXPECT_HR(hr, S_OK);
10782     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10783
10784     len = sizeof(buffW)/sizeof(WCHAR);
10785     buffW[0] = 0;
10786     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10787     EXPECT_HR(hr, S_OK);
10788     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10789
10790     IMXNamespaceManager_Release(nsmgr);
10791
10792     free_bstrs();
10793 }
10794
10795 static const DOMNodeType nodetypes_test[] =
10796 {
10797     NODE_ELEMENT,
10798     NODE_ATTRIBUTE,
10799     NODE_TEXT,
10800     NODE_CDATA_SECTION,
10801     NODE_ENTITY_REFERENCE,
10802     NODE_PROCESSING_INSTRUCTION,
10803     NODE_COMMENT,
10804     NODE_DOCUMENT_FRAGMENT,
10805     NODE_INVALID
10806 };
10807
10808 static void test_dispex(void)
10809 {
10810     const DOMNodeType *type = nodetypes_test;
10811     IXMLDOMImplementation *impl;
10812     IXMLDOMNodeList *node_list;
10813     IXMLDOMParseError *error;
10814     IXMLDOMNamedNodeMap *map;
10815     IXSLProcessor *processor;
10816     IXSLTemplate *template;
10817     IXMLDOMDocument *doc;
10818     IXMLHTTPRequest *req;
10819     IXMLDOMElement *elem;
10820     IDispatchEx *dispex;
10821     IXMLDOMNode *node;
10822     VARIANT_BOOL b;
10823     IUnknown *unk;
10824     HRESULT hr;
10825     DISPID did;
10826
10827     doc = create_document(&IID_IXMLDOMDocument);
10828
10829     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10830     test_domobj_dispex(unk);
10831     IUnknown_Release(unk);
10832
10833     for(; *type != NODE_INVALID; type++)
10834     {
10835         IXMLDOMNode *node;
10836         VARIANT v;
10837
10838         V_VT(&v) = VT_I2;
10839         V_I2(&v) = *type;
10840
10841         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10842         ok(hr == S_OK, "failed to create node type %d\n", *type);
10843
10844         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10845
10846         test_domobj_dispex(unk);
10847         IUnknown_Release(unk);
10848         IXMLDOMNode_Release(node);
10849     }
10850
10851     /* IXMLDOMNodeList */
10852     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10853     EXPECT_HR(hr, S_OK);
10854     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10855     test_domobj_dispex(unk);
10856     IUnknown_Release(unk);
10857     IXMLDOMNodeList_Release(node_list);
10858
10859     /* IXMLDOMNodeList for children list */
10860     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10861     EXPECT_HR(hr, S_OK);
10862     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10863     test_domobj_dispex(unk);
10864     IUnknown_Release(unk);
10865
10866     /* collection dispex test, empty collection */
10867     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10868     EXPECT_HR(hr, S_OK);
10869     did = 0;
10870     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10871     EXPECT_HR(hr, S_OK);
10872     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10873     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10874     EXPECT_HR(hr, S_OK);
10875     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10876     IDispatchEx_Release(dispex);
10877
10878     IXMLDOMNodeList_Release(node_list);
10879
10880     /* IXMLDOMParseError */
10881     hr = IXMLDOMDocument_get_parseError(doc, &error);
10882     EXPECT_HR(hr, S_OK);
10883     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
10884     test_domobj_dispex(unk);
10885     IUnknown_Release(unk);
10886     IXMLDOMParseError_Release(error);
10887
10888     /* IXMLDOMNamedNodeMap */
10889     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10890     EXPECT_HR(hr, S_OK);
10891
10892     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
10893     EXPECT_HR(hr, S_OK);
10894     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10895     EXPECT_HR(hr, S_OK);
10896     IXMLDOMNodeList_Release(node_list);
10897
10898     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10899     EXPECT_HR(hr, S_OK);
10900     IXMLDOMNode_Release(node);
10901     hr = IXMLDOMElement_get_attributes(elem, &map);
10902     EXPECT_HR(hr, S_OK);
10903     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
10904     test_domobj_dispex(unk);
10905     IUnknown_Release(unk);
10906     /* collection dispex test */
10907     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10908     EXPECT_HR(hr, S_OK);
10909     did = 0;
10910     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10911     EXPECT_HR(hr, S_OK);
10912     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10913     IDispatchEx_Release(dispex);
10914
10915     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
10916     EXPECT_HR(hr, S_OK);
10917     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10918     EXPECT_HR(hr, S_OK);
10919     IXMLDOMNodeList_Release(node_list);
10920     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10921     EXPECT_HR(hr, S_OK);
10922     IXMLDOMNode_Release(node);
10923     hr = IXMLDOMElement_get_attributes(elem, &map);
10924     EXPECT_HR(hr, S_OK);
10925     /* collection dispex test, empty collection */
10926     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10927     EXPECT_HR(hr, S_OK);
10928     did = 0;
10929     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10930     EXPECT_HR(hr, S_OK);
10931     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10932     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10933     EXPECT_HR(hr, S_OK);
10934     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10935     IDispatchEx_Release(dispex);
10936
10937     IXMLDOMNamedNodeMap_Release(map);
10938     IXMLDOMElement_Release(elem);
10939
10940     /* IXMLDOMImplementation */
10941     hr = IXMLDOMDocument_get_implementation(doc, &impl);
10942     EXPECT_HR(hr, S_OK);
10943
10944     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
10945     EXPECT_HR(hr, S_OK);
10946     IDispatchEx_Release(dispex);
10947     IXMLDOMImplementation_Release(impl);
10948
10949     IXMLDOMDocument_Release(doc);
10950
10951     /* IXMLHTTPRequest */
10952     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
10953         &IID_IXMLHttpRequest, (void**)&req);
10954     if (hr == S_OK)
10955     {
10956         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
10957         EXPECT_HR(hr, E_NOINTERFACE);
10958         IXMLHTTPRequest_Release(req);
10959     }
10960
10961     /* IXSLTemplate */
10962     template = create_xsltemplate(&IID_IXSLTemplate);
10963     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
10964     EXPECT_HR(hr, S_OK);
10965     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
10966     EXPECT_HR(hr, S_OK);
10967     test_domobj_dispex(unk);
10968     IUnknown_Release(unk);
10969     IDispatchEx_Release(dispex);
10970
10971     /* IXSLProcessor */
10972     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
10973     EXPECT_HR(hr, S_OK);
10974     b = VARIANT_FALSE;
10975     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
10976     EXPECT_HR(hr, S_OK);
10977     ok(b == VARIANT_TRUE, "got %d\n", b);
10978
10979     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
10980     EXPECT_HR(hr, S_OK);
10981     IXMLDOMDocument_Release(doc);
10982
10983     hr = IXSLTemplate_createProcessor(template, &processor);
10984     EXPECT_HR(hr, S_OK);
10985     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
10986     EXPECT_HR(hr, S_OK);
10987     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
10988     EXPECT_HR(hr, S_OK);
10989     test_domobj_dispex(unk);
10990     IUnknown_Release(unk);
10991     IDispatchEx_Release(dispex);
10992
10993     IXSLProcessor_Release(processor);
10994     IXSLTemplate_Release(template);
10995
10996     free_bstrs();
10997 }
10998
10999 static void test_parseerror(void)
11000 {
11001     IXMLDOMParseError2 *error2;
11002     IXMLDOMParseError *error;
11003     IXMLDOMDocument *doc;
11004     HRESULT hr;
11005
11006     doc = create_document(&IID_IXMLDOMDocument);
11007
11008     hr = IXMLDOMDocument_get_parseError(doc, &error);
11009     EXPECT_HR(hr, S_OK);
11010
11011     hr = IXMLDOMParseError_get_line(error, NULL);
11012     EXPECT_HR(hr, E_INVALIDARG);
11013
11014     hr = IXMLDOMParseError_get_srcText(error, NULL);
11015     EXPECT_HR(hr, E_INVALIDARG);
11016
11017     hr = IXMLDOMParseError_get_linepos(error, NULL);
11018     EXPECT_HR(hr, E_INVALIDARG);
11019
11020     IXMLDOMParseError_Release(error);
11021     IXMLDOMDocument_Release(doc);
11022
11023     doc = create_document_version(60, &IID_IXMLDOMDocument);
11024     if (!doc) return;
11025     hr = IXMLDOMDocument_get_parseError(doc, &error);
11026     EXPECT_HR(hr, S_OK);
11027     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11028     EXPECT_HR(hr, S_OK);
11029     IXMLDOMParseError2_Release(error2);
11030     IXMLDOMParseError_Release(error);
11031     IXMLDOMDocument_Release(doc);
11032 }
11033
11034 static void test_getAttributeNode(void)
11035 {
11036     IXMLDOMAttribute *attr;
11037     IXMLDOMDocument *doc;
11038     IXMLDOMElement *elem;
11039     VARIANT_BOOL v;
11040     HRESULT hr;
11041     BSTR str;
11042
11043     doc = create_document(&IID_IXMLDOMDocument);
11044
11045     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11046     EXPECT_HR(hr, S_OK);
11047
11048     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11049     EXPECT_HR(hr, S_OK);
11050
11051     str = SysAllocString(nonexistent_fileW);
11052     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11053     EXPECT_HR(hr, E_FAIL);
11054
11055     attr = (IXMLDOMAttribute*)0xdeadbeef;
11056     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11057     EXPECT_HR(hr, E_FAIL);
11058     ok(attr == NULL, "got %p\n", attr);
11059     SysFreeString(str);
11060
11061     str = SysAllocString(nonexistent_attrW);
11062     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11063     EXPECT_HR(hr, S_FALSE);
11064
11065     attr = (IXMLDOMAttribute*)0xdeadbeef;
11066     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11067     EXPECT_HR(hr, S_FALSE);
11068     ok(attr == NULL, "got %p\n", attr);
11069     SysFreeString(str);
11070
11071     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11072     EXPECT_HR(hr, S_OK);
11073     IXMLDOMAttribute_Release(attr);
11074
11075     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11076     EXPECT_HR(hr, S_FALSE);
11077
11078     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11079     EXPECT_HR(hr, S_OK);
11080     IXMLDOMAttribute_Release(attr);
11081
11082     IXMLDOMElement_Release(elem);
11083     IXMLDOMDocument_Release(doc);
11084     free_bstrs();
11085 }
11086
11087 typedef struct {
11088     DOMNodeType type;
11089     const char *name;
11090     REFIID iids[3];
11091 } supporterror_t;
11092
11093 static const supporterror_t supporterror_test[] = {
11094     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11095     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11096     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11097     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11098     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11099     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11100     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11101     { NODE_INVALID }
11102 };
11103
11104 static void test_supporterrorinfo(void)
11105 {
11106     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11107                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11108     const supporterror_t *ptr = supporterror_test;
11109     ISupportErrorInfo *errorinfo, *info2;
11110     IXMLDOMNamedNodeMap *map, *map2;
11111     IXMLDOMDocument *doc;
11112     IXMLDOMElement *elem;
11113     VARIANT_BOOL b;
11114     IUnknown *unk;
11115     REFIID *iid;
11116     void *dummy;
11117     HRESULT hr;
11118
11119     doc = create_document_version(60, &IID_IXMLDOMDocument3);
11120     if (!doc) return;
11121
11122     EXPECT_REF(doc, 1);
11123     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11124     EXPECT_HR(hr, S_OK);
11125     EXPECT_REF(doc, 1);
11126     ISupportErrorInfo_AddRef(errorinfo);
11127     EXPECT_REF(errorinfo, 2);
11128     EXPECT_REF(doc, 1);
11129     ISupportErrorInfo_Release(errorinfo);
11130
11131     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11132     EXPECT_HR(hr, S_OK);
11133     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11134
11135     /* error interface can't be queried back for DOM interface */
11136     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11137     EXPECT_HR(hr, E_NOINTERFACE);
11138     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11139     EXPECT_HR(hr, E_NOINTERFACE);
11140
11141     ISupportErrorInfo_Release(info2);
11142
11143     iid = iids;
11144     while (*iid)
11145     {
11146         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11147         EXPECT_HR(hr, S_OK);
11148         if (hr == S_OK)
11149         {
11150             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11151             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11152             IUnknown_Release(unk);
11153         }
11154
11155         iid++;
11156     }
11157
11158     ISupportErrorInfo_Release(errorinfo);
11159
11160     while (ptr->type != NODE_INVALID)
11161     {
11162         IXMLDOMNode *node;
11163         VARIANT type;
11164
11165         V_VT(&type) = VT_I1;
11166         V_I1(&type) = ptr->type;
11167
11168         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11169         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11170
11171         EXPECT_REF(node, 1);
11172         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11173         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11174         EXPECT_REF(node, 1);
11175
11176         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11177         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11178
11179         iid = ptr->iids;
11180
11181         while (*iid)
11182         {
11183             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11184             if (hr == S_OK)
11185             {
11186                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11187                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11188                 IUnknown_Release(unk);
11189             }
11190
11191             iid++;
11192         }
11193
11194         ISupportErrorInfo_Release(errorinfo);
11195         IXMLDOMNode_Release(node);
11196         ptr++;
11197     }
11198
11199     /* IXMLDOMNamedNodeMap */
11200     b = VARIANT_FALSE;
11201     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11202     EXPECT_HR(hr, S_OK);
11203     ok(b == VARIANT_TRUE, "got %d\n", b);
11204
11205     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11206     EXPECT_HR(hr, S_OK);
11207
11208     hr = IXMLDOMElement_get_attributes(elem, &map);
11209     EXPECT_HR(hr, S_OK);
11210
11211     EXPECT_REF(map, 1);
11212     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11213     EXPECT_HR(hr, S_OK);
11214     EXPECT_REF(map, 2);
11215
11216     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11217     EXPECT_HR(hr, S_OK);
11218
11219     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11220     EXPECT_HR(hr, S_OK);
11221     ok(map == map2, "got %p\n", map2);
11222     IXMLDOMNamedNodeMap_Release(map2);
11223
11224     EXPECT_REF(errorinfo, 2);
11225     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11226     EXPECT_HR(hr, S_OK);
11227     EXPECT_REF(errorinfo, 3);
11228     EXPECT_REF(map, 3);
11229     IUnknown_Release(unk);
11230
11231     ISupportErrorInfo_Release(errorinfo);
11232     IXMLDOMNamedNodeMap_Release(map);
11233     IXMLDOMElement_Release(elem);
11234
11235     IXMLDOMDocument_Release(doc);
11236     free_bstrs();
11237 }
11238
11239 typedef struct {
11240     DOMNodeType type;
11241     const char *name;
11242     const char *put_content;
11243     HRESULT put_hr;
11244     VARTYPE get_vt;
11245     HRESULT get_hr;
11246 } node_value_t;
11247
11248 static const node_value_t nodevalue_test[] = {
11249     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11250     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11251     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11252     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11253     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11254     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11255     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11256     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11257     { NODE_INVALID }
11258 };
11259
11260 static void test_nodeValue(void)
11261 {
11262     const node_value_t *ptr = nodevalue_test;
11263     IXMLDOMDocument *doc;
11264     HRESULT hr;
11265
11266     doc = create_document(&IID_IXMLDOMDocument);
11267     if (!doc) return;
11268
11269     while (ptr->type != NODE_INVALID)
11270     {
11271         IXMLDOMNode *node;
11272         VARIANT v;
11273
11274         V_VT(&v) = VT_I2;
11275         V_I2(&v) = ptr->type;
11276
11277         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11278         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11279
11280         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11281         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11282
11283         V_VT(&v) = VT_BSTR;
11284         V_BSTR(&v) = _bstr_(ptr->put_content);
11285         hr = IXMLDOMNode_put_nodeValue(node, v);
11286         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11287
11288         V_VT(&v) = VT_EMPTY;
11289         hr = IXMLDOMNode_get_nodeValue(node, &v);
11290         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11291         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11292         if (hr == S_OK)
11293             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11294                 wine_dbgstr_w(V_BSTR(&v)));
11295         VariantClear(&v);
11296
11297         IXMLDOMNode_Release(node);
11298
11299         ptr++;
11300     }
11301
11302     IXMLDOMDocument_Release(doc);
11303 }
11304
11305 static const char namespacesA[] =
11306 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11307 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11308 "     <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11309 "     <ns1:elem3/>"
11310 "     <ns1:elem4/>"
11311 "     <elem5 xmlns=\"http://blahblah.org\"/>"
11312 "     <ns1:elem6>true</ns1:elem6>"
11313 "   </ns1:elem1>";
11314
11315 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11316 static const char xsd_schema1_xml[] =
11317 "<?xml version='1.0'?>"
11318 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11319 "            targetNamespace='x-schema:test1.xsd'>"
11320 "   <element name='root'>"
11321 "       <complexType>"
11322 "           <sequence maxOccurs='unbounded'>"
11323 "               <any/>"
11324 "           </sequence>"
11325 "       </complexType>"
11326 "   </element>"
11327 "</schema>";
11328
11329 static void test_get_namespaces(void)
11330 {
11331     IXMLDOMSchemaCollection *collection, *collection2;
11332     IXMLDOMDocument2 *doc, *doc2;
11333     IEnumVARIANT *enumv;
11334     IXMLDOMNode *node;
11335     VARIANT_BOOL b;
11336     HRESULT hr;
11337     VARIANT v;
11338     LONG len;
11339     BSTR s;
11340
11341     doc = create_document(&IID_IXMLDOMDocument2);
11342     if (!doc) return;
11343
11344     /* null pointer */
11345     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11346     EXPECT_HR(hr, E_POINTER);
11347
11348     /* no document loaded */
11349     collection = (void*)0xdeadbeef;
11350     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11351     EXPECT_HR(hr, S_OK);
11352     if (hr != S_OK)
11353     {
11354         IXMLDOMDocument_Release(doc);
11355         return;
11356     }
11357     EXPECT_REF(collection, 2);
11358
11359     collection2 = (void*)0xdeadbeef;
11360     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11361     EXPECT_HR(hr, S_OK);
11362     ok(collection == collection2, "got %p\n", collection2);
11363     EXPECT_REF(collection, 3);
11364     IXMLDOMSchemaCollection_Release(collection);
11365
11366     len = -1;
11367     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11368     EXPECT_HR(hr, S_OK);
11369     ok(len == 0, "got %d\n", len);
11370     IXMLDOMSchemaCollection_Release(collection);
11371
11372     /* now with document */
11373     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11374     EXPECT_HR(hr, S_OK);
11375
11376     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11377     EXPECT_HR(hr, S_OK);
11378
11379     len = -1;
11380     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11381     EXPECT_HR(hr, S_OK);
11382     ok(len == 2, "got %d\n", len);
11383
11384     /* try to lookup some uris */
11385     node = (void*)0xdeadbeef;
11386     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11387     EXPECT_HR(hr, S_OK);
11388     ok(node == NULL, "got %p\n", node);
11389
11390     node = (void*)0xdeadbeef;
11391     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11392     EXPECT_HR(hr, S_OK);
11393     ok(node == NULL, "got %p\n", node);
11394
11395     /* load schema and try to add it */
11396     doc2 = create_document(&IID_IXMLDOMDocument2);
11397     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11398     EXPECT_HR(hr, S_OK);
11399
11400     V_VT(&v) = VT_DISPATCH;
11401     V_DISPATCH(&v) = (IDispatch*)doc2;
11402     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11403     EXPECT_HR(hr, E_FAIL);
11404
11405     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11406     EXPECT_HR(hr, S_OK);
11407     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11408     SysFreeString(s);
11409
11410     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11411     EXPECT_HR(hr, S_OK);
11412     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11413     SysFreeString(s);
11414
11415     s = (void*)0xdeadbeef;
11416     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11417     EXPECT_HR(hr, E_FAIL);
11418     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11419
11420     /* enumerate */
11421     enumv = (void*)0xdeadbeef;
11422     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11423 todo_wine
11424     EXPECT_HR(hr, S_OK);
11425     if (hr == S_OK)
11426     {
11427         ok(enumv != NULL, "got %p\n", enumv);
11428
11429         V_VT(&v) = VT_EMPTY;
11430         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11431         EXPECT_HR(hr, S_OK);
11432         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11433         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11434         VariantClear(&v);
11435
11436         V_VT(&v) = VT_EMPTY;
11437         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11438         EXPECT_HR(hr, S_OK);
11439         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11440         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11441         VariantClear(&v);
11442
11443         V_VT(&v) = VT_NULL;
11444         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11445         EXPECT_HR(hr, S_FALSE);
11446         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11447
11448         IEnumVARIANT_Release(enumv);
11449     }
11450     IXMLDOMSchemaCollection_Release(collection);
11451
11452     IXMLDOMDocument2_Release(doc);
11453
11454     /* now with CLSID_DOMDocument60 */
11455     doc = create_document_version(60, &IID_IXMLDOMDocument2);
11456     if (!doc) return;
11457
11458     /* null pointer */
11459     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11460     EXPECT_HR(hr, E_POINTER);
11461
11462     /* no document loaded */
11463     collection = (void*)0xdeadbeef;
11464     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11465     EXPECT_HR(hr, S_OK);
11466     if (hr != S_OK)
11467     {
11468         IXMLDOMDocument_Release(doc);
11469         return;
11470     }
11471     EXPECT_REF(collection, 2);
11472
11473     collection2 = (void*)0xdeadbeef;
11474     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11475     EXPECT_HR(hr, S_OK);
11476     ok(collection == collection2, "got %p\n", collection2);
11477     EXPECT_REF(collection, 3);
11478     IXMLDOMSchemaCollection_Release(collection);
11479
11480     len = -1;
11481     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11482     EXPECT_HR(hr, S_OK);
11483     ok(len == 0, "got %d\n", len);
11484     IXMLDOMSchemaCollection_Release(collection);
11485
11486     /* now with document */
11487     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11488     EXPECT_HR(hr, S_OK);
11489
11490     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11491     EXPECT_HR(hr, S_OK);
11492
11493     len = -1;
11494     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11495     EXPECT_HR(hr, S_OK);
11496     ok(len == 2, "got %d\n", len);
11497
11498     /* try to lookup some uris */
11499     node = (void*)0xdeadbeef;
11500     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11501     EXPECT_HR(hr, E_NOTIMPL);
11502     ok(node == (void*)0xdeadbeef, "got %p\n", node);
11503
11504     /* load schema and try to add it */
11505     doc2 = create_document(&IID_IXMLDOMDocument2);
11506     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11507     EXPECT_HR(hr, S_OK);
11508
11509     V_VT(&v) = VT_DISPATCH;
11510     V_DISPATCH(&v) = (IDispatch*)doc2;
11511     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11512     EXPECT_HR(hr, E_FAIL);
11513     IXMLDOMSchemaCollection_Release(doc2);
11514
11515     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11516     EXPECT_HR(hr, S_OK);
11517     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11518     SysFreeString(s);
11519
11520     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11521     EXPECT_HR(hr, S_OK);
11522     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11523     SysFreeString(s);
11524
11525     s = (void*)0xdeadbeef;
11526     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11527     EXPECT_HR(hr, E_FAIL);
11528     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11529
11530     /* enumerate */
11531     enumv = (void*)0xdeadbeef;
11532     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11533 todo_wine
11534     EXPECT_HR(hr, S_OK);
11535     if (hr == S_OK)
11536     {
11537         ok(enumv != NULL, "got %p\n", enumv);
11538
11539         V_VT(&v) = VT_EMPTY;
11540         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11541         EXPECT_HR(hr, S_OK);
11542         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11543         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11544         VariantClear(&v);
11545
11546         V_VT(&v) = VT_EMPTY;
11547         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11548         EXPECT_HR(hr, S_OK);
11549         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11550         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11551         VariantClear(&v);
11552
11553         V_VT(&v) = VT_NULL;
11554         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11555         EXPECT_HR(hr, S_FALSE);
11556         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11557
11558         IEnumVARIANT_Release(enumv);
11559     }
11560     IXMLDOMSchemaCollection_Release(collection);
11561     IXMLDOMDocument2_Release(doc);
11562     free_bstrs();
11563 }
11564
11565 START_TEST(domdoc)
11566 {
11567     IXMLDOMDocument *doc;
11568     IUnknown *unk;
11569     HRESULT hr;
11570
11571     hr = CoInitialize( NULL );
11572     ok( hr == S_OK, "failed to init com\n");
11573     if (hr != S_OK) return;
11574
11575     test_XMLHTTP();
11576
11577     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
11578     if (hr != S_OK)
11579     {
11580         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
11581         return;
11582     }
11583
11584     IXMLDOMDocument_Release(doc);
11585
11586     test_domdoc();
11587     test_persiststreaminit();
11588     test_domnode();
11589     test_refs();
11590     test_create();
11591     test_getElementsByTagName();
11592     test_get_text();
11593     test_get_childNodes();
11594     test_get_firstChild();
11595     test_get_lastChild();
11596     test_removeChild();
11597     test_replaceChild();
11598     test_removeNamedItem();
11599     test_IXMLDOMDocument2();
11600     test_whitespace();
11601     test_XPath();
11602     test_XSLPattern();
11603     test_cloneNode();
11604     test_xmlTypes();
11605     test_save();
11606     test_testTransforms();
11607     test_namespaces();
11608     test_FormattingXML();
11609     test_nodeTypedValue();
11610     test_TransformWithLoadingLocalFile();
11611     test_put_nodeValue();
11612     test_document_IObjectSafety();
11613     test_splitText();
11614     test_getQualifiedItem();
11615     test_removeQualifiedItem();
11616     test_get_ownerDocument();
11617     test_setAttributeNode();
11618     test_put_dataType();
11619     test_createNode();
11620     test_get_prefix();
11621     test_default_properties();
11622     test_selectSingleNode();
11623     test_events();
11624     test_createProcessingInstruction();
11625     test_put_nodeTypedValue();
11626     test_get_xml();
11627     test_insertBefore();
11628     test_appendChild();
11629     test_get_doctype();
11630     test_get_tagName();
11631     test_get_dataType();
11632     test_get_nodeTypeString();
11633     test_get_attributes();
11634     test_selection();
11635     test_load();
11636     test_dispex();
11637     test_parseerror();
11638     test_getAttributeNode();
11639     test_supporterrorinfo();
11640     test_nodeValue();
11641     test_get_namespaces();
11642
11643     test_xsltemplate();
11644
11645     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11646         &IID_IMXNamespaceManager, (void**)&unk);
11647     if (hr == S_OK)
11648     {
11649         test_mxnamespacemanager();
11650         test_mxnamespacemanager_override();
11651
11652         IUnknown_Release(unk);
11653     }
11654     else
11655         win_skip("MXNamespaceManager is not available\n");
11656
11657     CoUninitialize();
11658 }