kernel32: GetModuleHandleEx already clears the module handle on failure.
[wine] / dlls / msxml3 / tests / domdoc.c
1 /*
2  * XML test
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2007-2008 Alistair Leslie-Hughes
6  * Copyright 2010-2011 Adam Martinson for CodeWeavers
7  * Copyright 2010-2012 Nikolay Sivov for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24
25 #define COBJMACROS
26 #define CONST_VTABLE
27
28 #include <stdio.h>
29 #include <assert.h>
30
31 #include "windows.h"
32
33 #include "msxml2.h"
34 #include "msxml2did.h"
35 #include "ole2.h"
36 #include "dispex.h"
37
38 #include "initguid.h"
39 #include "objsafe.h"
40 #include "mshtml.h"
41
42 #include "wine/test.h"
43
44 /* undef the #define in msxml2 so that we can access all versions */
45 #undef CLSID_DOMDocument
46
47 DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
48 DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
49 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
50
51 #define DEFINE_EXPECT(func) \
52     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
53
54 #define SET_EXPECT(func) \
55     expect_ ## func = TRUE
56
57 #define CHECK_EXPECT2(func) \
58     do { \
59         ok(expect_ ##func, "unexpected call " #func "\n"); \
60         called_ ## func = TRUE; \
61     }while(0)
62
63 #define CHECK_CALLED(func) \
64     do { \
65         ok(called_ ## func, "expected " #func "\n"); \
66         expect_ ## func = called_ ## func = FALSE; \
67     }while(0)
68
69 static const char *debugstr_guid(REFIID riid)
70 {
71     static char buf[50];
72
73     if(!riid)
74         return "(null)";
75
76     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
77             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
78             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
79             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
80
81     return buf;
82 }
83
84 static int g_unexpectedcall, g_expectedcall;
85
86 typedef struct
87 {
88     IDispatch IDispatch_iface;
89     LONG ref;
90 } dispevent;
91
92 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
93 {
94     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
95 }
96
97 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
98 {
99     *ppvObject = NULL;
100
101     if ( IsEqualGUID( riid, &IID_IDispatch) ||
102          IsEqualGUID( riid, &IID_IUnknown) )
103     {
104         *ppvObject = iface;
105     }
106     else
107         return E_NOINTERFACE;
108
109     IDispatch_AddRef( iface );
110
111     return S_OK;
112 }
113
114 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
115 {
116     dispevent *This = impl_from_IDispatch( iface );
117     return InterlockedIncrement( &This->ref );
118 }
119
120 static ULONG WINAPI dispevent_Release(IDispatch *iface)
121 {
122     dispevent *This = impl_from_IDispatch( iface );
123     ULONG ref = InterlockedDecrement( &This->ref );
124
125     if (ref == 0)
126         HeapFree(GetProcessHeap(), 0, This);
127
128     return ref;
129 }
130
131 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
132 {
133     g_unexpectedcall++;
134     *pctinfo = 0;
135     return S_OK;
136 }
137
138 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
139         LCID lcid, ITypeInfo **ppTInfo)
140 {
141     g_unexpectedcall++;
142     return S_OK;
143 }
144
145 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
146         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
147 {
148     g_unexpectedcall++;
149     return S_OK;
150 }
151
152 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
153         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
154         EXCEPINFO *excepInfo, UINT *argErr)
155 {
156     ok(member == 0, "expected 0 member, got %d\n", member);
157     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
158     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
159
160     ok(params->cArgs == 0, "got %d\n", params->cArgs);
161     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
162     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
163     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
164
165     ok(result == NULL, "got %p\n", result);
166     ok(excepInfo == NULL, "got %p\n", excepInfo);
167     ok(argErr == NULL, "got %p\n", argErr);
168
169     g_expectedcall++;
170     return E_FAIL;
171 }
172
173 static const IDispatchVtbl dispeventVtbl =
174 {
175     dispevent_QueryInterface,
176     dispevent_AddRef,
177     dispevent_Release,
178     dispevent_GetTypeInfoCount,
179     dispevent_GetTypeInfo,
180     dispevent_GetIDsOfNames,
181     dispevent_Invoke
182 };
183
184 static IDispatch* create_dispevent(void)
185 {
186     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
187
188     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
189     event->ref = 1;
190
191     return (IDispatch*)&event->IDispatch_iface;
192 }
193
194 /* object site */
195 DEFINE_EXPECT(site_qi_IServiceProvider);
196 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
197 DEFINE_EXPECT(site_qi_IOleClientSite);
198
199 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
200 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
201 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
202 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
203 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
204
205 DEFINE_EXPECT(htmldoc2_get_all);
206 DEFINE_EXPECT(htmldoc2_get_url);
207 DEFINE_EXPECT(collection_get_length);
208
209 typedef struct
210 {
211     IServiceProvider IServiceProvider_iface;
212 } testprov_t;
213
214 testprov_t testprov;
215
216 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
217 {
218     *ppvObject = NULL;
219
220     if (IsEqualGUID(riid, &IID_IServiceProvider))
221         CHECK_EXPECT2(site_qi_IServiceProvider);
222
223     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
224         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
225
226     if (IsEqualGUID(riid, &IID_IOleClientSite))
227         CHECK_EXPECT2(site_qi_IOleClientSite);
228
229     if (IsEqualGUID(riid, &IID_IUnknown))
230          *ppvObject = iface;
231     else if (IsEqualGUID(riid, &IID_IServiceProvider))
232          *ppvObject = &testprov.IServiceProvider_iface;
233
234     if (*ppvObject) IUnknown_AddRef(iface);
235
236     return *ppvObject ? S_OK : E_NOINTERFACE;
237 }
238
239 static ULONG WINAPI site_AddRef(IUnknown *iface)
240 {
241     return 2;
242 }
243
244 static ULONG WINAPI site_Release(IUnknown *iface)
245 {
246     return 1;
247 }
248
249 static const IUnknownVtbl testsiteVtbl =
250 {
251     site_QueryInterface,
252     site_AddRef,
253     site_Release
254 };
255
256 typedef struct
257 {
258     IUnknown IUnknown_iface;
259 } testsite_t;
260
261 static testsite_t testsite = { { &testsiteVtbl } };
262
263 /* test IHTMLElementCollection */
264 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
265 {
266     ok(0, "unexpected call\n");
267     *ppvObject = NULL;
268     return E_NOINTERFACE;
269 }
270
271 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
272 {
273     return 2;
274 }
275
276 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
277 {
278     return 1;
279 }
280
281 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
282 {
283     ok(0, "unexpected call\n");
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
288                                                 LCID lcid, ITypeInfo **ppTInfo)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
295                                                 LPOLESTR *rgszNames, UINT cNames,
296                                                 LCID lcid, DISPID *rgDispId)
297 {
298     ok(0, "unexpected call\n");
299     return E_NOTIMPL;
300 }
301
302 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
303                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
304                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
305 {
306     ok(0, "unexpected call\n");
307     return E_NOTIMPL;
308 }
309
310 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
311 {
312     ok(0, "unexpected call\n");
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
317 {
318     ok(0, "unexpected call\n");
319     return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
323 {
324     CHECK_EXPECT2(collection_get_length);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
329 {
330     ok(0, "unexpected call\n");
331     return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
335 {
336     ok(0, "unexpected call\n");
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
341 {
342     ok(0, "unexpected call\n");
343     return E_NOTIMPL;
344 }
345
346 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
347     htmlecoll_QueryInterface,
348     htmlecoll_AddRef,
349     htmlecoll_Release,
350     htmlecoll_GetTypeInfoCount,
351     htmlecoll_GetTypeInfo,
352     htmlecoll_GetIDsOfNames,
353     htmlecoll_Invoke,
354
355     htmlecoll_toString,
356     htmlecoll_put_length,
357     htmlecoll_get_length,
358     htmlecoll_get__newEnum,
359     htmlecoll_item,
360     htmlecoll_tags
361 };
362
363 typedef struct
364 {
365     IHTMLElementCollection IHTMLElementCollection_iface;
366 } testhtmlecoll_t;
367
368 static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
369
370 /* test IHTMLDocument2 */
371 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
372 {
373    trace("\n");
374    *ppvObject = NULL;
375    return E_NOINTERFACE;
376 }
377
378 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
379 {
380     return 2;
381 }
382
383 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
384 {
385     return 1;
386 }
387
388 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
389 {
390     ok(0, "unexpected call\n");
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
395                                                 LCID lcid, ITypeInfo **ppTInfo)
396 {
397     ok(0, "unexpected call\n");
398     return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
402                                                 LPOLESTR *rgszNames, UINT cNames,
403                                                 LCID lcid, DISPID *rgDispId)
404 {
405     ok(0, "unexpected call\n");
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
410                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
411                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
412 {
413     ok(0, "unexpected call\n");
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
418 {
419     ok(0, "unexpected call\n");
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
424 {
425     CHECK_EXPECT2(htmldoc2_get_all);
426     *p = &htmlecoll.IHTMLElementCollection_iface;
427     return S_OK;
428 }
429
430 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
431 {
432     ok(0, "unexpected call\n");
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
437 {
438     ok(0, "unexpected call\n");
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
443 {
444     ok(0, "unexpected call\n");
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
449 {
450     ok(0, "unexpected call\n");
451     return E_NOTIMPL;
452 }
453
454 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
455 {
456     ok(0, "unexpected call\n");
457     return E_NOTIMPL;
458 }
459
460 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
461 {
462     ok(0, "unexpected call\n");
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
467 {
468     ok(0, "unexpected call\n");
469     return E_NOTIMPL;
470 }
471
472 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
473 {
474     ok(0, "unexpected call\n");
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
479 {
480     ok(0, "unexpected call\n");
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
485 {
486     ok(0, "unexpected call\n");
487     return E_NOTIMPL;
488 }
489
490 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
491 {
492     ok(0, "unexpected call\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
497 {
498     ok(0, "unexpected call\n");
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
503 {
504     ok(0, "unexpected call\n");
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
509 {
510     ok(0, "unexpected call\n");
511     return E_NOTIMPL;
512 }
513
514 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
515 {
516     ok(0, "unexpected call\n");
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
521 {
522     ok(0, "unexpected call\n");
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
527 {
528     ok(0, "unexpected call\n");
529     return E_NOTIMPL;
530 }
531
532 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
533 {
534     ok(0, "unexpected call\n");
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
539 {
540     ok(0, "unexpected call\n");
541     return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
545 {
546     ok(0, "unexpected call\n");
547     return E_NOTIMPL;
548 }
549
550 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
551 {
552     ok(0, "unexpected call\n");
553     return E_NOTIMPL;
554 }
555
556 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
557 {
558     ok(0, "unexpected call\n");
559     return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
563 {
564     ok(0, "unexpected call\n");
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
569 {
570     ok(0, "unexpected call\n");
571     return E_NOTIMPL;
572 }
573
574 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
575 {
576     ok(0, "unexpected call\n");
577     return E_NOTIMPL;
578 }
579
580 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
581 {
582     ok(0, "unexpected call\n");
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
587 {
588     ok(0, "unexpected call\n");
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
593 {
594     ok(0, "unexpected call\n");
595     return E_NOTIMPL;
596 }
597
598 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
599 {
600     ok(0, "unexpected call\n");
601     return E_NOTIMPL;
602 }
603
604 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
605 {
606     ok(0, "unexpected call\n");
607     return E_NOTIMPL;
608 }
609
610 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
611 {
612     ok(0, "unexpected call\n");
613     return E_NOTIMPL;
614 }
615
616 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
617 {
618     CHECK_EXPECT2(htmldoc2_get_url);
619     *p = SysAllocString(NULL);
620     return S_OK;
621 }
622
623 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
624 {
625     ok(0, "unexpected call\n");
626     return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
630 {
631     ok(0, "unexpected call\n");
632     return E_NOTIMPL;
633 }
634
635 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
636 {
637     ok(0, "unexpected call\n");
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
642 {
643     ok(0, "unexpected call\n");
644     return E_NOTIMPL;
645 }
646
647 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
648 {
649     ok(0, "unexpected call\n");
650     return E_NOTIMPL;
651 }
652
653 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
654 {
655     ok(0, "unexpected call\n");
656     return E_NOTIMPL;
657 }
658
659 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
660 {
661     ok(0, "unexpected call\n");
662     return E_NOTIMPL;
663 }
664
665 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
666 {
667     ok(0, "unexpected call\n");
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
672 {
673     ok(0, "unexpected call\n");
674     return E_NOTIMPL;
675 }
676
677 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
678 {
679     ok(0, "unexpected call\n");
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
684 {
685     ok(0, "unexpected call\n");
686     return E_NOTIMPL;
687 }
688
689 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
690 {
691     ok(0, "unexpected call\n");
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
696 {
697     ok(0, "unexpected call\n");
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
708 {
709     ok(0, "unexpected call\n");
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
714 {
715     ok(0, "unexpected call\n");
716     return E_NOTIMPL;
717 }
718
719 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
720 {
721     ok(0, "unexpected call\n");
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
726 {
727     ok(0, "unexpected call\n");
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
732 {
733     ok(0, "unexpected call\n");
734     return E_NOTIMPL;
735 }
736
737 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
738 {
739     ok(0, "unexpected call\n");
740     return E_NOTIMPL;
741 }
742
743 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
744                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
745 {
746     ok(0, "unexpected call\n");
747     return E_NOTIMPL;
748 }
749
750 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
751 {
752     ok(0, "unexpected call\n");
753     return E_NOTIMPL;
754 }
755
756 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
757 {
758     ok(0, "unexpected call\n");
759     return E_NOTIMPL;
760 }
761
762 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
763                                                         VARIANT_BOOL *pfRet)
764 {
765     ok(0, "unexpected call\n");
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
770                                                         VARIANT_BOOL *pfRet)
771 {
772     ok(0, "unexpected call\n");
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
777                                                         VARIANT_BOOL *pfRet)
778 {
779     ok(0, "unexpected call\n");
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
784                                                         VARIANT_BOOL *pfRet)
785 {
786     ok(0, "unexpected call\n");
787     return E_NOTIMPL;
788 }
789
790 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
791                                                         BSTR *pfRet)
792 {
793     ok(0, "unexpected call\n");
794     return E_NOTIMPL;
795 }
796
797 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
798                                                         VARIANT *pfRet)
799 {
800     ok(0, "unexpected call\n");
801     return E_NOTIMPL;
802 }
803
804 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
805                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
806 {
807     ok(0, "unexpected call\n");
808     return E_NOTIMPL;
809 }
810
811 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
812                                                         VARIANT_BOOL *pfRet)
813 {
814     ok(0, "unexpected call\n");
815     return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
819                                                  IHTMLElement **newElem)
820 {
821     ok(0, "unexpected call\n");
822     return E_NOTIMPL;
823 }
824
825 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
826 {
827     ok(0, "unexpected call\n");
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
832 {
833     ok(0, "unexpected call\n");
834     return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
838 {
839     ok(0, "unexpected call\n");
840     return E_NOTIMPL;
841 }
842
843 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
844 {
845     ok(0, "unexpected call\n");
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
850 {
851     ok(0, "unexpected call\n");
852     return E_NOTIMPL;
853 }
854
855 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
856 {
857     ok(0, "unexpected call\n");
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
862 {
863     ok(0, "unexpected call\n");
864     return E_NOTIMPL;
865 }
866
867 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
868 {
869     ok(0, "unexpected call\n");
870     return E_NOTIMPL;
871 }
872
873 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
874 {
875     ok(0, "unexpected call\n");
876     return E_NOTIMPL;
877 }
878
879 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
880 {
881     ok(0, "unexpected call\n");
882     return E_NOTIMPL;
883 }
884
885 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
886 {
887     ok(0, "unexpected call\n");
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
892 {
893     ok(0, "unexpected call\n");
894     return E_NOTIMPL;
895 }
896
897 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
898 {
899     ok(0, "unexpected call\n");
900     return E_NOTIMPL;
901 }
902
903 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
904 {
905     ok(0, "unexpected call\n");
906     return E_NOTIMPL;
907 }
908
909 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
910 {
911     ok(0, "unexpected call\n");
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
916 {
917     ok(0, "unexpected call\n");
918     return E_NOTIMPL;
919 }
920
921 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
922 {
923     ok(0, "unexpected call\n");
924     return E_NOTIMPL;
925 }
926
927 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
928 {
929     ok(0, "unexpected call\n");
930     return E_NOTIMPL;
931 }
932
933 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
934 {
935     ok(0, "unexpected call\n");
936     return E_NOTIMPL;
937 }
938
939 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
940 {
941     ok(0, "unexpected call\n");
942     return E_NOTIMPL;
943 }
944
945 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
946 {
947     ok(0, "unexpected call\n");
948     return E_NOTIMPL;
949 }
950
951 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
952 {
953     ok(0, "unexpected call\n");
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
958 {
959     ok(0, "unexpected call\n");
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
964 {
965     ok(0, "unexpected call\n");
966     return E_NOTIMPL;
967 }
968
969 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
970 {
971     ok(0, "unexpected call\n");
972     return E_NOTIMPL;
973 }
974
975 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
976 {
977     ok(0, "unexpected call\n");
978     return E_NOTIMPL;
979 }
980
981 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
982 {
983     ok(0, "unexpected call\n");
984     return E_NOTIMPL;
985 }
986
987 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
988 {
989     ok(0, "unexpected call\n");
990     return E_NOTIMPL;
991 }
992
993 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
994 {
995     ok(0, "unexpected call\n");
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
1000 {
1001     ok(0, "unexpected call\n");
1002     return E_NOTIMPL;
1003 }
1004
1005 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1006 {
1007     ok(0, "unexpected call\n");
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1012 {
1013     ok(0, "unexpected call\n");
1014     return E_NOTIMPL;
1015 }
1016
1017 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1018 {
1019     ok(0, "unexpected call\n");
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1024 {
1025     ok(0, "unexpected call\n");
1026     return E_NOTIMPL;
1027 }
1028
1029 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1030                                                         IHTMLElement **elementHit)
1031 {
1032     ok(0, "unexpected call\n");
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1037 {
1038     ok(0, "unexpected call\n");
1039     return E_NOTIMPL;
1040 }
1041
1042 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
1043                                                    IHTMLStyleSheetsCollection **p)
1044 {
1045     ok(0, "unexpected call\n");
1046     return E_NOTIMPL;
1047 }
1048
1049 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1050 {
1051     ok(0, "unexpected call\n");
1052     return E_NOTIMPL;
1053 }
1054
1055 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1056 {
1057     ok(0, "unexpected call\n");
1058     return E_NOTIMPL;
1059 }
1060
1061 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1062 {
1063     ok(0, "unexpected call\n");
1064     return E_NOTIMPL;
1065 }
1066
1067 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1068 {
1069     ok(0, "unexpected call\n");
1070     return E_NOTIMPL;
1071 }
1072
1073 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
1074 {
1075     ok(0, "unexpected call\n");
1076     return E_NOTIMPL;
1077 }
1078
1079 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1080                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1081 {
1082     ok(0, "unexpected call\n");
1083     return E_NOTIMPL;
1084 }
1085
1086 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
1087     htmldoc2_QueryInterface,
1088     htmldoc2_AddRef,
1089     htmldoc2_Release,
1090     htmldoc2_GetTypeInfoCount,
1091     htmldoc2_GetTypeInfo,
1092     htmldoc2_GetIDsOfNames,
1093     htmldoc2_Invoke,
1094     htmldoc2_get_Script,
1095     htmldoc2_get_all,
1096     htmldoc2_get_body,
1097     htmldoc2_get_activeElement,
1098     htmldoc2_get_images,
1099     htmldoc2_get_applets,
1100     htmldoc2_get_links,
1101     htmldoc2_get_forms,
1102     htmldoc2_get_anchors,
1103     htmldoc2_put_title,
1104     htmldoc2_get_title,
1105     htmldoc2_get_scripts,
1106     htmldoc2_put_designMode,
1107     htmldoc2_get_designMode,
1108     htmldoc2_get_selection,
1109     htmldoc2_get_readyState,
1110     htmldoc2_get_frames,
1111     htmldoc2_get_embeds,
1112     htmldoc2_get_plugins,
1113     htmldoc2_put_alinkColor,
1114     htmldoc2_get_alinkColor,
1115     htmldoc2_put_bgColor,
1116     htmldoc2_get_bgColor,
1117     htmldoc2_put_fgColor,
1118     htmldoc2_get_fgColor,
1119     htmldoc2_put_linkColor,
1120     htmldoc2_get_linkColor,
1121     htmldoc2_put_vlinkColor,
1122     htmldoc2_get_vlinkColor,
1123     htmldoc2_get_referrer,
1124     htmldoc2_get_location,
1125     htmldoc2_get_lastModified,
1126     htmldoc2_put_URL,
1127     htmldoc2_get_URL,
1128     htmldoc2_put_domain,
1129     htmldoc2_get_domain,
1130     htmldoc2_put_cookie,
1131     htmldoc2_get_cookie,
1132     htmldoc2_put_expando,
1133     htmldoc2_get_expando,
1134     htmldoc2_put_charset,
1135     htmldoc2_get_charset,
1136     htmldoc2_put_defaultCharset,
1137     htmldoc2_get_defaultCharset,
1138     htmldoc2_get_mimeType,
1139     htmldoc2_get_fileSize,
1140     htmldoc2_get_fileCreatedDate,
1141     htmldoc2_get_fileModifiedDate,
1142     htmldoc2_get_fileUpdatedDate,
1143     htmldoc2_get_security,
1144     htmldoc2_get_protocol,
1145     htmldoc2_get_nameProp,
1146     htmldoc2_write,
1147     htmldoc2_writeln,
1148     htmldoc2_open,
1149     htmldoc2_close,
1150     htmldoc2_clear,
1151     htmldoc2_queryCommandSupported,
1152     htmldoc2_queryCommandEnabled,
1153     htmldoc2_queryCommandState,
1154     htmldoc2_queryCommandIndeterm,
1155     htmldoc2_queryCommandText,
1156     htmldoc2_queryCommandValue,
1157     htmldoc2_execCommand,
1158     htmldoc2_execCommandShowHelp,
1159     htmldoc2_createElement,
1160     htmldoc2_put_onhelp,
1161     htmldoc2_get_onhelp,
1162     htmldoc2_put_onclick,
1163     htmldoc2_get_onclick,
1164     htmldoc2_put_ondblclick,
1165     htmldoc2_get_ondblclick,
1166     htmldoc2_put_onkeyup,
1167     htmldoc2_get_onkeyup,
1168     htmldoc2_put_onkeydown,
1169     htmldoc2_get_onkeydown,
1170     htmldoc2_put_onkeypress,
1171     htmldoc2_get_onkeypress,
1172     htmldoc2_put_onmouseup,
1173     htmldoc2_get_onmouseup,
1174     htmldoc2_put_onmousedown,
1175     htmldoc2_get_onmousedown,
1176     htmldoc2_put_onmousemove,
1177     htmldoc2_get_onmousemove,
1178     htmldoc2_put_onmouseout,
1179     htmldoc2_get_onmouseout,
1180     htmldoc2_put_onmouseover,
1181     htmldoc2_get_onmouseover,
1182     htmldoc2_put_onreadystatechange,
1183     htmldoc2_get_onreadystatechange,
1184     htmldoc2_put_onafterupdate,
1185     htmldoc2_get_onafterupdate,
1186     htmldoc2_put_onrowexit,
1187     htmldoc2_get_onrowexit,
1188     htmldoc2_put_onrowenter,
1189     htmldoc2_get_onrowenter,
1190     htmldoc2_put_ondragstart,
1191     htmldoc2_get_ondragstart,
1192     htmldoc2_put_onselectstart,
1193     htmldoc2_get_onselectstart,
1194     htmldoc2_elementFromPoint,
1195     htmldoc2_get_parentWindow,
1196     htmldoc2_get_styleSheets,
1197     htmldoc2_put_onbeforeupdate,
1198     htmldoc2_get_onbeforeupdate,
1199     htmldoc2_put_onerrorupdate,
1200     htmldoc2_get_onerrorupdate,
1201     htmldoc2_toString,
1202     htmldoc2_createStyleSheet
1203 };
1204
1205 typedef struct
1206 {
1207     IHTMLDocument2 IHTMLDocument2_iface;
1208 } testhtmldoc2_t;
1209
1210 static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
1211
1212 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1213 {
1214     *ppvObject = NULL;
1215
1216     if (IsEqualGUID(riid, &IID_IUnknown) ||
1217         IsEqualGUID(riid, &IID_IServiceProvider))
1218     {
1219         *ppvObject = iface;
1220         IServiceProvider_AddRef(iface);
1221         return S_OK;
1222     }
1223
1224     ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
1225
1226     return E_NOINTERFACE;
1227 }
1228
1229 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1230 {
1231     return 2;
1232 }
1233
1234 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1235 {
1236     return 1;
1237 }
1238
1239 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1240 {
1241     *obj = NULL;
1242
1243     if (IsEqualGUID(service, &SID_SBindHost) &&
1244         IsEqualGUID(riid, &IID_IBindHost))
1245     {
1246         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1247     }
1248     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1249              IsEqualGUID(riid, &IID_IHTMLDocument2))
1250     {
1251         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1252     }
1253     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1254              IsEqualGUID(riid, &IID_IHTMLDocument2))
1255     {
1256         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1257         *obj = &htmldoc2.IHTMLDocument2_iface;
1258         return S_OK;
1259     }
1260     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1261              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1262     {
1263         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1264     }
1265     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1266              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1267     {
1268         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1269     }
1270     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1271              IsEqualGUID(riid, &IID_IStream))
1272     {
1273         /* FIXME: unidentified service id */
1274     }
1275     else
1276         ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
1277
1278     return E_NOTIMPL;
1279 }
1280
1281 static const IServiceProviderVtbl testprovVtbl =
1282 {
1283     sp_QueryInterface,
1284     sp_AddRef,
1285     sp_Release,
1286     sp_QueryService
1287 };
1288
1289 testprov_t testprov = { { &testprovVtbl } };
1290
1291 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1292 static void _expect_children(IXMLDOMNode *node, int line)
1293 {
1294     VARIANT_BOOL b;
1295     HRESULT hr;
1296
1297     b = VARIANT_FALSE;
1298     hr = IXMLDOMNode_hasChildNodes(node, &b);
1299     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1300     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1301 }
1302
1303 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1304 static void _expect_no_children(IXMLDOMNode *node, int line)
1305 {
1306     VARIANT_BOOL b;
1307     HRESULT hr;
1308
1309     b = VARIANT_TRUE;
1310     hr = IXMLDOMNode_hasChildNodes(node, &b);
1311     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1312     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1313 }
1314
1315 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1316 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1317 {
1318     ULONG rc = IUnknown_AddRef(obj);
1319     IUnknown_Release(obj);
1320     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1321 }
1322
1323 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1324 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1325 {
1326     LONG length;
1327     HRESULT hr;
1328
1329     length = 0;
1330     hr = IXMLDOMNodeList_get_length(list, &length);
1331     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1332     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1333 }
1334
1335 #define EXPECT_HR(hr,hr_exp) \
1336     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1337
1338 static const WCHAR szEmpty[] = { 0 };
1339 static const WCHAR szIncomplete[] = {
1340     '<','?','x','m','l',' ',
1341     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1342 };
1343 static const WCHAR szComplete1[] = {
1344     '<','?','x','m','l',' ',
1345     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1346     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1347 };
1348 static const WCHAR szComplete2[] = {
1349     '<','?','x','m','l',' ',
1350     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1351     '<','o','>','<','/','o','>','\n',0
1352 };
1353 static const WCHAR szComplete3[] = {
1354     '<','?','x','m','l',' ',
1355     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1356     '<','a','>','<','/','a','>','\n',0
1357 };
1358 static const char complete4A[] =
1359     "<?xml version=\'1.0\'?>\n"
1360     "<lc dl=\'str1\'>\n"
1361         "<bs vr=\'str2\' sz=\'1234\'>"
1362             "fn1.txt\n"
1363         "</bs>\n"
1364         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1365             "fn2.txt\n"
1366         "</pr>\n"
1367         "<empty></empty>\n"
1368         "<fo>\n"
1369             "<ba>\n"
1370                 "f1\n"
1371             "</ba>\n"
1372         "</fo>\n"
1373     "</lc>\n";
1374
1375 static const WCHAR szComplete5[] = {
1376     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1377     'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
1378     ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
1379         '<','S',':','s','c','o','p','e','>',
1380             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1381         '<','/','S',':','s','c','o','p','e','>',
1382         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1383             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1384             'c','o','m','p','u','t','e','r',
1385         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1386     '<','/','S',':','s','e','a','r','c','h','>',0
1387 };
1388
1389 static const WCHAR szComplete6[] = {
1390     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1391     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1392     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1393 };
1394
1395 static const CHAR szNonUnicodeXML[] =
1396 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1397 "<open></open>\n";
1398
1399 static const char szExampleXML[] =
1400 "<?xml version='1.0' encoding='utf-8'?>\n"
1401 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1402 "    <elem>\n"
1403 "        <a>A1 field</a>\n"
1404 "        <b>B1 field</b>\n"
1405 "        <c>C1 field</c>\n"
1406 "        <d>D1 field</d>\n"
1407 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1408 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1409 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1410 "            </html>\n"
1411 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1412 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1413 "            </html>\n"
1414 "        </description>\n"
1415 "    </elem>\n"
1416 "\n"
1417 "    <elem>\n"
1418 "        <a>A2 field</a>\n"
1419 "        <b>B2 field</b>\n"
1420 "        <c type=\"old\">C2 field</c>\n"
1421 "        <d>D2 field</d>\n"
1422 "    </elem>\n"
1423 "\n"
1424 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1425 "        <a>A3 field</a>\n"
1426 "        <b>B3 field</b>\n"
1427 "        <c>C3 field</c>\n"
1428 "    </elem>\n"
1429 "\n"
1430 "    <elem>\n"
1431 "        <a>A4 field</a>\n"
1432 "        <b>B4 field</b>\n"
1433 "        <foo:c>C4 field</foo:c>\n"
1434 "        <d>D4 field</d>\n"
1435 "    </elem>\n"
1436 "</root>\n";
1437
1438 static const CHAR szNodeTypesXML[] =
1439 "<?xml version='1.0'?>"
1440 "<!-- comment node 0 -->"
1441 "<root id='0' depth='0'>"
1442 "   <!-- comment node 1 -->"
1443 "   text node 0"
1444 "   <x id='1' depth='1'>"
1445 "       <?foo value='PI for x'?>"
1446 "       <!-- comment node 2 -->"
1447 "       text node 1"
1448 "       <a id='3' depth='2'/>"
1449 "       <b id='4' depth='2'/>"
1450 "       <c id='5' depth='2'/>"
1451 "   </x>"
1452 "   <y id='2' depth='1'>"
1453 "       <?bar value='PI for y'?>"
1454 "       <!-- comment node 3 -->"
1455 "       text node 2"
1456 "       <a id='6' depth='2'/>"
1457 "       <b id='7' depth='2'/>"
1458 "       <c id='8' depth='2'/>"
1459 "   </y>"
1460 "</root>";
1461
1462 static const CHAR szTransformXML[] =
1463 "<?xml version=\"1.0\"?>\n"
1464 "<greeting>\n"
1465 "Hello World\n"
1466 "</greeting>";
1467
1468 static  const CHAR szTransformSSXML[] =
1469 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1470 "   <xsl:output method=\"html\"/>\n"
1471 "   <xsl:template match=\"/\">\n"
1472 "       <xsl:apply-templates select=\"greeting\"/>\n"
1473 "   </xsl:template>\n"
1474 "   <xsl:template match=\"greeting\">\n"
1475 "       <html>\n"
1476 "           <body>\n"
1477 "               <h1>\n"
1478 "                   <xsl:value-of select=\".\"/>\n"
1479 "               </h1>\n"
1480 "           </body>\n"
1481 "       </html>\n"
1482 "   </xsl:template>\n"
1483 "</xsl:stylesheet>";
1484
1485 static  const CHAR szTransformOutput[] =
1486 "<html><body><h1>"
1487 "Hello World"
1488 "</h1></body></html>";
1489
1490 static const CHAR szTypeValueXML[] =
1491 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1492 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1493 "   <string>Wine</string>\n"
1494 "   <string2 dt:dt=\"string\">String</string2>\n"
1495 "   <number dt:dt=\"number\">12.44</number>\n"
1496 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1497 "   <int dt:dt=\"int\">-13</int>\n"
1498 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1499 "   <bool dt:dt=\"boolean\">1</bool>\n"
1500 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1501 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1502 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1503 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1504 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1505 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1506 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1507 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1508 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1509 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1510 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1511 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1512 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1513 "   <float dt:dt=\"float\">41221.421</float>\n"
1514 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1515 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1516 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1517 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1518 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1519 "</root>";
1520
1521 static const CHAR szBasicTransformSSXMLPart1[] =
1522 "<?xml version=\"1.0\"?>"
1523 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1524 "<xsl:output method=\"html\"/>\n"
1525 "<xsl:template match=\"/\">"
1526 "<HTML><BODY><TABLE>"
1527 "        <xsl:apply-templates select='document(\"";
1528
1529 static const CHAR szBasicTransformSSXMLPart2[] =
1530 "\")/bottle/wine'>"
1531 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1532 "        </xsl:apply-templates>"
1533 "</TABLE></BODY></HTML>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"bottle\">"
1536 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1537 "</xsl:template>"
1538 "<xsl:template match=\"name\">"
1539 "   <TD><xsl:apply-templates /></TD>"
1540 "</xsl:template>"
1541 "<xsl:template match=\"cost\">"
1542 "   <TD><xsl:apply-templates /></TD>"
1543 "</xsl:template>"
1544 "</xsl:stylesheet>";
1545
1546 static const CHAR szBasicTransformXML[] =
1547 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1548
1549 static const CHAR szBasicTransformOutput[] =
1550 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1551
1552 #define SZ_EMAIL_DTD \
1553 "<!DOCTYPE email ["\
1554 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1555 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1556 "       <!ATTLIST email sent (yes|no) \"no\">"\
1557 "   <!ELEMENT recipients    (to+,cc*)>"\
1558 "   <!ELEMENT to            (#PCDATA)>"\
1559 "       <!ATTLIST to name CDATA #IMPLIED>"\
1560 "   <!ELEMENT cc            (#PCDATA)>"\
1561 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1562 "   <!ELEMENT from          (#PCDATA)>"\
1563 "       <!ATTLIST from name CDATA #IMPLIED>"\
1564 "   <!ELEMENT reply-to      (#PCDATA)>"\
1565 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1566 "   <!ELEMENT subject       ANY>"\
1567 "   <!ELEMENT body          ANY>"\
1568 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1569 "   <!ELEMENT attachment    (#PCDATA)>"\
1570 "       <!ATTLIST attachment id ID #REQUIRED>"\
1571 "]>"
1572
1573 static const CHAR szEmailXML[] =
1574 "<?xml version=\"1.0\"?>"
1575 SZ_EMAIL_DTD
1576 "<email attachments=\"patch1\">"
1577 "   <recipients>"
1578 "       <to>wine-patches@winehq.org</to>"
1579 "   </recipients>"
1580 "   <from name=\"Anonymous\">user@localhost</from>"
1581 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1582 "   <body>"
1583 "       It no longer causes spontaneous combustion..."
1584 "   </body>"
1585 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1586 "</email>";
1587
1588 static const CHAR szEmailXML_0D[] =
1589 "<?xml version=\"1.0\"?>"
1590 SZ_EMAIL_DTD
1591 "<email attachments=\"patch1\">"
1592 "   <recipients>"
1593 "       <to>wine-patches@winehq.org</to>"
1594 "   </recipients>"
1595 "   <from name=\"Anonymous\">user@localhost</from>"
1596 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1597 "   <body>"
1598 "       <undecl />"
1599 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1600 "   </body>"
1601 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1602 "</email>";
1603
1604 static const CHAR szEmailXML_0E[] =
1605 "<?xml version=\"1.0\"?>"
1606 SZ_EMAIL_DTD
1607 "<email attachments=\"patch1\">"
1608 "   <recipients>"
1609 "       <to>wine-patches@winehq.org</to>"
1610 "   </recipients>"
1611 "   <from name=\"Anonymous\">user@localhost</from>"
1612 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1613 "   <body>"
1614 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1615 "   </body>"
1616 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1617 "</email>";
1618
1619 static const CHAR szEmailXML_11[] =
1620 "<?xml version=\"1.0\"?>"
1621 SZ_EMAIL_DTD
1622 "<email attachments=\"patch1\">"
1623 "   <recipients>"
1624 "   </recipients>"
1625 "   <from name=\"Anonymous\">user@localhost</from>"
1626 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1627 "   <body>"
1628 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1629 "   </body>"
1630 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1631 "</email>";
1632
1633 static const CHAR szEmailXML_13[] =
1634 "<?xml version=\"1.0\"?>"
1635 SZ_EMAIL_DTD
1636 "<msg attachments=\"patch1\">"
1637 "   <recipients>"
1638 "       <to>wine-patches@winehq.org</to>"
1639 "   </recipients>"
1640 "   <from name=\"Anonymous\">user@localhost</from>"
1641 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1642 "   <body>"
1643 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1644 "   </body>"
1645 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1646 "</msg>";
1647
1648 static const CHAR szEmailXML_14[] =
1649 "<?xml version=\"1.0\"?>"
1650 SZ_EMAIL_DTD
1651 "<email attachments=\"patch1\">"
1652 "   <to>wine-patches@winehq.org</to>"
1653 "   <from name=\"Anonymous\">user@localhost</from>"
1654 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1655 "   <body>"
1656 "       XML_INVALID_CONTENT 0xC00CE014"
1657 "   </body>"
1658 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1659 "</email>";
1660
1661 static const CHAR szEmailXML_15[] =
1662 "<?xml version=\"1.0\"?>"
1663 SZ_EMAIL_DTD
1664 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1665 "   <recipients>"
1666 "       <to>wine-patches@winehq.org</to>"
1667 "   </recipients>"
1668 "   <from name=\"Anonymous\">user@localhost</from>"
1669 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1670 "   <body>"
1671 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1672 "   </body>"
1673 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1674 "</email>";
1675
1676 static const CHAR szEmailXML_16[] =
1677 "<?xml version=\"1.0\"?>"
1678 SZ_EMAIL_DTD
1679 "<email attachments=\"patch1\">"
1680 "   <recipients>"
1681 "       <to>wine-patches@winehq.org</to>"
1682 "   </recipients>"
1683 "   <from name=\"Anonymous\">user@localhost</from>"
1684 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1685 "   <body enc=\"ASCII\">"
1686 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1687 "   </body>"
1688 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1689 "</email>";
1690
1691 static const CHAR szEmailXML_17[] =
1692 "<?xml version=\"1.0\"?>"
1693 SZ_EMAIL_DTD
1694 "<email attachments=\"patch1\" sent=\"true\">"
1695 "   <recipients>"
1696 "       <to>wine-patches@winehq.org</to>"
1697 "   </recipients>"
1698 "   <from name=\"Anonymous\">user@localhost</from>"
1699 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1700 "   <body>"
1701 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1702 "   </body>"
1703 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1704 "</email>";
1705
1706 static const CHAR szEmailXML_18[] =
1707 "<?xml version=\"1.0\"?>"
1708 SZ_EMAIL_DTD
1709 "<email attachments=\"patch1\">"
1710 "   oops"
1711 "   <recipients>"
1712 "       <to>wine-patches@winehq.org</to>"
1713 "   </recipients>"
1714 "   <from name=\"Anonymous\">user@localhost</from>"
1715 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1716 "   <body>"
1717 "       XML_ILLEGAL_TEXT 0xC00CE018"
1718 "   </body>"
1719 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1720 "</email>";
1721
1722 static const CHAR szEmailXML_20[] =
1723 "<?xml version=\"1.0\"?>"
1724 SZ_EMAIL_DTD
1725 "<email>"
1726 "   <recipients>"
1727 "       <to>wine-patches@winehq.org</to>"
1728 "   </recipients>"
1729 "   <from name=\"Anonymous\">user@localhost</from>"
1730 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1731 "   <body>"
1732 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1733 "   </body>"
1734 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1735 "</email>";
1736
1737 static const char xpath_simple_list[] =
1738 "<?xml version=\"1.0\"?>"
1739 "<root>"
1740 "   <a attr1=\"1\" attr2=\"2\" />"
1741 "   <b/>"
1742 "   <c/>"
1743 "   <d/>"
1744 "</root>";
1745
1746 static const char default_ns_doc[] = {
1747     "<?xml version=\"1.0\"?>"
1748     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1749     "    d=\"d attr\" />"
1750 };
1751
1752 static const WCHAR nonexistent_fileW[] = {
1753     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1754 };
1755 static const WCHAR nonexistent_attrW[] = {
1756     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1757 };
1758 static const WCHAR szDocument[] = {
1759     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1760 };
1761
1762 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1763 static WCHAR szdl[] = { 'd','l',0 };
1764 static const WCHAR szvr[] = { 'v','r',0 };
1765 static const WCHAR szlc[] = { 'l','c',0 };
1766 static WCHAR szbs[] = { 'b','s',0 };
1767 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1768 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1769 static const WCHAR szstar[] = { '*',0 };
1770 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1771
1772 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1773 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1774 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1775
1776 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1777 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1778 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1779 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1780                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1781 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1782                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1783
1784 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1785 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1786
1787 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1788                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1789 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1790                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1791                              '!',']',']','>',0};
1792 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1793 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1794
1795 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1796 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1797 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1798
1799 #define expect_bstr_eq_and_free(bstr, expect) { \
1800     BSTR bstrExp = alloc_str_from_narrow(expect); \
1801     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1802     SysFreeString(bstr); \
1803     SysFreeString(bstrExp); \
1804 }
1805
1806 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1807
1808 #define ole_check(expr) { \
1809     HRESULT r = expr; \
1810     ok(r == S_OK, #expr " returned %x\n", r); \
1811 }
1812
1813 #define ole_expect(expr, expect) { \
1814     HRESULT r = expr; \
1815     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1816 }
1817
1818 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1819
1820 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1821 {
1822     void *obj = NULL;
1823     HRESULT hr;
1824
1825     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1826     if (hr != S_OK)
1827         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1828
1829     return obj;
1830 }
1831
1832 #define _create(cls) cls, #cls
1833
1834 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1835 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1836 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1837 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1838 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1839
1840 static BSTR alloc_str_from_narrow(const char *str)
1841 {
1842     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1843     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1844     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1845     return ret;
1846 }
1847
1848 static BSTR alloced_bstrs[256];
1849 static int alloced_bstrs_count;
1850
1851 static BSTR _bstr_(const char *str)
1852 {
1853     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1854     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1855     return alloced_bstrs[alloced_bstrs_count++];
1856 }
1857
1858 static void free_bstrs(void)
1859 {
1860     int i;
1861     for (i = 0; i < alloced_bstrs_count; i++)
1862         SysFreeString(alloced_bstrs[i]);
1863     alloced_bstrs_count = 0;
1864 }
1865
1866 static VARIANT _variantbstr_(const char *str)
1867 {
1868     VARIANT v;
1869     V_VT(&v) = VT_BSTR;
1870     V_BSTR(&v) = _bstr_(str);
1871     return v;
1872 }
1873
1874 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1875 {
1876     for (;;)
1877     {
1878         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1879         while (*sRight == '\r' || *sRight == '\n') sRight++;
1880         if (*sLeft != *sRight) return FALSE;
1881         if (!*sLeft) return TRUE;
1882         sLeft++;
1883         sRight++;
1884     }
1885 }
1886
1887 static void get_str_for_type(DOMNodeType type, char *buf)
1888 {
1889     switch (type)
1890     {
1891         case NODE_ATTRIBUTE:
1892             strcpy(buf, "A");
1893             break;
1894         case NODE_ELEMENT:
1895             strcpy(buf, "E");
1896             break;
1897         case NODE_DOCUMENT:
1898             strcpy(buf, "D");
1899             break;
1900         case NODE_TEXT:
1901             strcpy(buf, "T");
1902             break;
1903         case NODE_COMMENT:
1904             strcpy(buf, "C");
1905             break;
1906         case NODE_PROCESSING_INSTRUCTION:
1907             strcpy(buf, "P");
1908             break;
1909         default:
1910             wsprintfA(buf, "[%d]", type);
1911     }
1912 }
1913
1914 static int get_node_position(IXMLDOMNode *node)
1915 {
1916     HRESULT r;
1917     int pos = 0;
1918
1919     IXMLDOMNode_AddRef(node);
1920     do
1921     {
1922         IXMLDOMNode *new_node;
1923
1924         pos++;
1925         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1926         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1927         IXMLDOMNode_Release(node);
1928         node = new_node;
1929     } while (r == S_OK);
1930     return pos;
1931 }
1932
1933 static void node_to_string(IXMLDOMNode *node, char *buf)
1934 {
1935     HRESULT r = S_OK;
1936     DOMNodeType type;
1937
1938     if (node == NULL)
1939     {
1940         lstrcpyA(buf, "(null)");
1941         return;
1942     }
1943
1944     IXMLDOMNode_AddRef(node);
1945     while (r == S_OK)
1946     {
1947         IXMLDOMNode *new_node;
1948
1949         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1950         get_str_for_type(type, buf);
1951         buf+=strlen(buf);
1952
1953         if (type == NODE_ATTRIBUTE)
1954         {
1955             BSTR bstr;
1956             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1957             *(buf++) = '\'';
1958             wsprintfA(buf, "%ws", bstr);
1959             buf += strlen(buf);
1960             *(buf++) = '\'';
1961             SysFreeString(bstr);
1962
1963             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1964         }
1965         else
1966         {
1967             r = IXMLDOMNode_get_parentNode(node, &new_node);
1968             wsprintf(buf, "%d", get_node_position(node));
1969             buf += strlen(buf);
1970         }
1971
1972         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1973         IXMLDOMNode_Release(node);
1974         node = new_node;
1975         if (r == S_OK)
1976             *(buf++) = '.';
1977     }
1978
1979     *buf = 0;
1980 }
1981
1982 static char *list_to_string(IXMLDOMNodeList *list)
1983 {
1984     static char buf[4096];
1985     char *pos = buf;
1986     LONG len = 0;
1987     int i;
1988
1989     if (list == NULL)
1990     {
1991         lstrcpyA(buf, "(null)");
1992         return buf;
1993     }
1994     ole_check(IXMLDOMNodeList_get_length(list, &len));
1995     for (i = 0; i < len; i++)
1996     {
1997         IXMLDOMNode *node;
1998         if (i > 0)
1999             *(pos++) = ' ';
2000         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2001         node_to_string(node, pos);
2002         pos += strlen(pos);
2003         IXMLDOMNode_Release(node);
2004     }
2005     *pos = 0;
2006     return buf;
2007 }
2008
2009 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
2010 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
2011
2012 struct docload_ret_t {
2013     VARIANT_BOOL b;
2014     HRESULT hr;
2015 };
2016
2017 struct leading_spaces_t {
2018     const CLSID *clsid;
2019     const char *name;
2020     struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
2021 };
2022
2023 static const struct leading_spaces_t leading_spaces_classdata[] = {
2024     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2025     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2026     { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2027     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2028     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2029     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2030     { NULL }
2031 };
2032
2033 static const char* leading_spaces_xmldata[] = {
2034     "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
2035     " <?xml version=\"1.0\"?><root/>",
2036     "\n<?xml version=\"1.0\"?><root/>",
2037     "\t<?xml version=\"1.0\"?><root/>",
2038     "\r\n<?xml version=\"1.0\"?><root/>",
2039     "\r<?xml version=\"1.0\"?><root/>",
2040     "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
2041     0
2042 };
2043
2044 static void test_domdoc( void )
2045 {
2046     HRESULT r, hr;
2047     IXMLDOMDocument *doc;
2048     IXMLDOMParseError *error;
2049     IXMLDOMElement *element = NULL;
2050     IXMLDOMNode *node;
2051     IXMLDOMText *nodetext = NULL;
2052     IXMLDOMComment *node_comment = NULL;
2053     IXMLDOMAttribute *node_attr = NULL;
2054     IXMLDOMNode *nodeChild = NULL;
2055     IXMLDOMProcessingInstruction *nodePI = NULL;
2056     const struct leading_spaces_t *class_ptr;
2057     const char **data_ptr;
2058     VARIANT_BOOL b;
2059     VARIANT var;
2060     BSTR str;
2061     LONG code, ref;
2062     LONG nLength = 0;
2063     WCHAR buff[100];
2064     int index;
2065
2066     /* Load document with leading spaces
2067      *
2068      * Test all CLSIDs with all test data XML strings
2069      */
2070     class_ptr = leading_spaces_classdata;
2071     index = 0;
2072     while (class_ptr->clsid)
2073     {
2074         HRESULT hr;
2075         int i;
2076
2077         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
2078              &IID_IXMLDOMDocument, (void**)&doc);
2079         if (hr != S_OK) {
2080             win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
2081             class_ptr++;
2082             index++;
2083             continue;
2084         }
2085
2086         data_ptr = leading_spaces_xmldata;
2087         i = 0;
2088         while (*data_ptr) {
2089             BSTR data = _bstr_(*data_ptr);
2090
2091             b = 0xc;
2092             V_VT(&var) = VT_BSTR;
2093             V_BSTR(&var) = data;
2094             hr = IXMLDOMDocument_load(doc, var, &b);
2095             EXPECT_HR(hr, class_ptr->ret[0].hr);
2096             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
2097
2098             b = 0xc;
2099             hr = IXMLDOMDocument_loadXML(doc, data, &b);
2100             EXPECT_HR(hr, class_ptr->ret[1].hr);
2101             ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
2102
2103             data_ptr++;
2104             i++;
2105         }
2106         class_ptr++;
2107         index++;
2108     }
2109
2110     doc = create_document(&IID_IXMLDOMDocument);
2111     if (!doc) return;
2112
2113 if (0)
2114 {
2115     /* crashes on native */
2116     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2117 }
2118
2119     /* try some stupid things */
2120     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2121     EXPECT_HR(hr, S_FALSE);
2122
2123     b = VARIANT_TRUE;
2124     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2125     EXPECT_HR(hr, S_FALSE);
2126     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2127
2128     /* try to load a document from a nonexistent file */
2129     b = VARIANT_TRUE;
2130     str = SysAllocString( nonexistent_fileW );
2131     VariantInit(&var);
2132     V_VT(&var) = VT_BSTR;
2133     V_BSTR(&var) = str;
2134
2135     r = IXMLDOMDocument_load( doc, var, &b);
2136     ok( r == S_FALSE, "loadXML succeeded\n");
2137     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2138     SysFreeString( str );
2139
2140     /* try load an empty document */
2141     b = VARIANT_TRUE;
2142     str = SysAllocString( szEmpty );
2143     r = IXMLDOMDocument_loadXML( doc, str, &b );
2144     ok( r == S_FALSE, "loadXML succeeded\n");
2145     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2146     SysFreeString( str );
2147
2148     r = IXMLDOMDocument_get_async( doc, &b );
2149     ok( r == S_OK, "get_async failed (%08x)\n", r);
2150     ok( b == VARIANT_TRUE, "Wrong default value\n");
2151
2152     /* check that there's no document element */
2153     element = NULL;
2154     r = IXMLDOMDocument_get_documentElement( doc, &element );
2155     ok( r == S_FALSE, "should be no document element\n");
2156
2157     /* try finding a node */
2158     node = NULL;
2159     str = SysAllocString( szstr1 );
2160     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2161     ok( r == S_FALSE, "ret %08x\n", r );
2162     SysFreeString( str );
2163
2164     b = VARIANT_TRUE;
2165     str = SysAllocString( szIncomplete );
2166     r = IXMLDOMDocument_loadXML( doc, str, &b );
2167     ok( r == S_FALSE, "loadXML succeeded\n");
2168     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2169     SysFreeString( str );
2170
2171     /* check that there's no document element */
2172     element = (IXMLDOMElement*)1;
2173     r = IXMLDOMDocument_get_documentElement( doc, &element );
2174     ok( r == S_FALSE, "should be no document element\n");
2175     ok( element == NULL, "Element should be NULL\n");
2176
2177     /* test for BSTR handling, pass broken BSTR */
2178     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2179     /* just a big length */
2180     *(DWORD*)buff = 0xf0f0;
2181     b = VARIANT_FALSE;
2182     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2183     ok( r == S_OK, "loadXML failed\n");
2184     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2185
2186     /* loadXML ignores the encoding attribute and always expects Unicode */
2187     b = VARIANT_FALSE;
2188     str = SysAllocString( szComplete6 );
2189     r = IXMLDOMDocument_loadXML( doc, str, &b );
2190     ok( r == S_OK, "loadXML failed\n");
2191     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2192     SysFreeString( str );
2193
2194     /* try a BSTR containing a Windows-1252 document */
2195     b = VARIANT_TRUE;
2196     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2197     r = IXMLDOMDocument_loadXML( doc, str, &b );
2198     ok( r == S_FALSE, "loadXML succeeded\n");
2199     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2200     SysFreeString( str );
2201
2202     /* try to load something valid */
2203     b = VARIANT_FALSE;
2204     str = SysAllocString( szComplete1 );
2205     r = IXMLDOMDocument_loadXML( doc, str, &b );
2206     ok( r == S_OK, "loadXML failed\n");
2207     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2208     SysFreeString( str );
2209
2210     /* check if nodename is correct */
2211     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2212     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2213
2214     str = (BSTR)0xdeadbeef;
2215     r = IXMLDOMDocument_get_baseName( doc, &str );
2216     ok ( r == S_FALSE, "got 0x%08x\n", r);
2217     ok (str == NULL, "got %p\n", str);
2218
2219     /* content doesn't matter here */
2220     str = NULL;
2221     r = IXMLDOMDocument_get_nodeName( doc, &str );
2222     ok ( r == S_OK, "get_nodeName wrong code\n");
2223     ok ( str != NULL, "str is null\n");
2224     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2225     SysFreeString( str );
2226
2227     /* test put_text */
2228     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2229     ok( r == E_FAIL, "ret %08x\n", r );
2230
2231     /* check that there's a document element */
2232     element = NULL;
2233     r = IXMLDOMDocument_get_documentElement( doc, &element );
2234     ok( r == S_OK, "should be a document element\n");
2235     if( element )
2236     {
2237         IObjectIdentity *ident;
2238
2239         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2240         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2241
2242         IXMLDOMElement_Release( element );
2243         element = NULL;
2244     }
2245
2246     /* as soon as we call loadXML again, the document element will disappear */
2247     b = 2;
2248     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2249     ok( r == S_FALSE, "loadXML failed\n");
2250     ok( b == 2, "variant modified\n");
2251     r = IXMLDOMDocument_get_documentElement( doc, &element );
2252     ok( r == S_FALSE, "should be no document element\n");
2253
2254     /* try to load something else simple and valid */
2255     b = VARIANT_FALSE;
2256     str = SysAllocString( szComplete3 );
2257     r = IXMLDOMDocument_loadXML( doc, str, &b );
2258     ok( r == S_OK, "loadXML failed\n");
2259     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2260     SysFreeString( str );
2261
2262     /* try something a little more complicated */
2263     b = FALSE;
2264     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2265     ok( r == S_OK, "loadXML failed\n");
2266     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2267
2268     r = IXMLDOMDocument_get_parseError( doc, &error );
2269     ok( r == S_OK, "returns %08x\n", r );
2270
2271     r = IXMLDOMParseError_get_errorCode( error, &code );
2272     ok( r == S_FALSE, "returns %08x\n", r );
2273     ok( code == 0, "code %d\n", code );
2274     IXMLDOMParseError_Release( error );
2275
2276     /* test createTextNode */
2277     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2278     ok( r == S_OK, "returns %08x\n", r );
2279     IXMLDOMText_Release(nodetext);
2280
2281     str = SysAllocString( szOpen );
2282     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2283     ok( r == E_INVALIDARG, "returns %08x\n", r );
2284     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2285     ok( r == S_OK, "returns %08x\n", r );
2286     SysFreeString( str );
2287     if(nodetext)
2288     {
2289         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2290         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2291
2292         /* Text Last Child Checks */
2293         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2294         ok(r == E_INVALIDARG, "ret %08x\n", r );
2295
2296         nodeChild = (IXMLDOMNode*)0x1;
2297         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2298         ok(r == S_FALSE, "ret %08x\n", r );
2299         ok(nodeChild == NULL, "nodeChild not NULL\n");
2300
2301         /* test length property */
2302         r = IXMLDOMText_get_length(nodetext, NULL);
2303         ok(r == E_INVALIDARG, "ret %08x\n", r );
2304
2305         r = IXMLDOMText_get_length(nodetext, &nLength);
2306         ok(r == S_OK, "ret %08x\n", r );
2307         ok(nLength == 4, "expected 4 got %d\n", nLength);
2308
2309         /* put data Tests */
2310         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2311         ok(r == S_OK, "ret %08x\n", r );
2312
2313         /* get data Tests */
2314         r = IXMLDOMText_get_data(nodetext, &str);
2315         ok(r == S_OK, "ret %08x\n", r );
2316         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2317         SysFreeString(str);
2318
2319         /* Confirm XML text is good */
2320         r = IXMLDOMText_get_xml(nodetext, &str);
2321         ok(r == S_OK, "ret %08x\n", r );
2322         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2323         SysFreeString(str);
2324
2325         /* Confirm we get the put_data Text back */
2326         r = IXMLDOMText_get_text(nodetext, &str);
2327         ok(r == S_OK, "ret %08x\n", r );
2328         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2329         SysFreeString(str);
2330
2331         /* test substringData */
2332         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2333         ok(r == E_INVALIDARG, "ret %08x\n", r );
2334
2335         /* test substringData - Invalid offset */
2336         str = (BSTR)&szElement;
2337         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2338         ok(r == E_INVALIDARG, "ret %08x\n", r );
2339         ok( str == NULL, "incorrect string\n");
2340
2341         /* test substringData - Invalid offset */
2342         str = (BSTR)&szElement;
2343         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2344         ok(r == S_FALSE, "ret %08x\n", r );
2345         ok( str == NULL, "incorrect string\n");
2346
2347         /* test substringData - Invalid size */
2348         str = (BSTR)&szElement;
2349         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2350         ok(r == E_INVALIDARG, "ret %08x\n", r );
2351         ok( str == NULL, "incorrect string\n");
2352
2353         /* test substringData - Invalid size */
2354         str = (BSTR)&szElement;
2355         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2356         ok(r == S_FALSE, "ret %08x\n", r );
2357         ok( str == NULL, "incorrect string\n");
2358
2359         /* test substringData - Start of string */
2360         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2361         ok(r == S_OK, "ret %08x\n", r );
2362         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2363         SysFreeString(str);
2364
2365         /* test substringData - Middle of string */
2366         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2367         ok(r == S_OK, "ret %08x\n", r );
2368         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2369         SysFreeString(str);
2370
2371         /* test substringData - End of string */
2372         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2373         ok(r == S_OK, "ret %08x\n", r );
2374         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2375         SysFreeString(str);
2376
2377         /* test appendData */
2378         r = IXMLDOMText_appendData(nodetext, NULL);
2379         ok(r == S_OK, "ret %08x\n", r );
2380
2381         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2382         ok(r == S_OK, "ret %08x\n", r );
2383
2384         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2385         ok(r == S_OK, "ret %08x\n", r );
2386
2387         r = IXMLDOMText_get_text(nodetext, &str);
2388         ok(r == S_OK, "ret %08x\n", r );
2389         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2390         SysFreeString(str);
2391
2392         /* test insertData */
2393         str = SysAllocStringLen(NULL, 0);
2394         r = IXMLDOMText_insertData(nodetext, -1, str);
2395         ok(r == S_OK, "ret %08x\n", r );
2396
2397         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2398         ok(r == S_OK, "ret %08x\n", r );
2399
2400         r = IXMLDOMText_insertData(nodetext, 1000, str);
2401         ok(r == S_OK, "ret %08x\n", r );
2402
2403         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2404         ok(r == S_OK, "ret %08x\n", r );
2405
2406         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2407         ok(r == S_OK, "ret %08x\n", r );
2408
2409         r = IXMLDOMText_insertData(nodetext, 0, str);
2410         ok(r == S_OK, "ret %08x\n", r );
2411         SysFreeString(str);
2412
2413         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2414         ok(r == E_INVALIDARG, "ret %08x\n", r );
2415
2416         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2417         ok(r == E_INVALIDARG, "ret %08x\n", r );
2418
2419         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2420         ok(r == S_OK, "ret %08x\n", r );
2421
2422         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2423         ok(r == S_OK, "ret %08x\n", r );
2424
2425         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2426         ok(r == S_OK, "ret %08x\n", r );
2427
2428         r = IXMLDOMText_get_text(nodetext, &str);
2429         ok(r == S_OK, "ret %08x\n", r );
2430         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2431         SysFreeString(str);
2432
2433         /* delete data */
2434         /* invalid arguments */
2435         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2436         ok(r == E_INVALIDARG, "ret %08x\n", r );
2437
2438         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2439         ok(r == S_OK, "ret %08x\n", r );
2440
2441         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2442         ok(r == E_INVALIDARG, "ret %08x\n", r );
2443
2444         r = IXMLDOMText_get_length(nodetext, &nLength);
2445         ok(r == S_OK, "ret %08x\n", r );
2446         ok(nLength == 43, "expected 43 got %d\n", nLength);
2447
2448         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2449         ok(r == S_OK, "ret %08x\n", r );
2450
2451         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2452         ok(r == E_INVALIDARG, "ret %08x\n", r );
2453
2454         /* delete from start */
2455         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2456         ok(r == S_OK, "ret %08x\n", r );
2457
2458         r = IXMLDOMText_get_length(nodetext, &nLength);
2459         ok(r == S_OK, "ret %08x\n", r );
2460         ok(nLength == 38, "expected 38 got %d\n", nLength);
2461
2462         r = IXMLDOMText_get_text(nodetext, &str);
2463         ok(r == S_OK, "ret %08x\n", r );
2464         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2465         SysFreeString(str);
2466
2467         /* delete from end */
2468         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2469         ok(r == S_OK, "ret %08x\n", r );
2470
2471         r = IXMLDOMText_get_length(nodetext, &nLength);
2472         ok(r == S_OK, "ret %08x\n", r );
2473         ok(nLength == 35, "expected 35 got %d\n", nLength);
2474
2475         r = IXMLDOMText_get_text(nodetext, &str);
2476         ok(r == S_OK, "ret %08x\n", r );
2477         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2478         SysFreeString(str);
2479
2480         /* delete from inside */
2481         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2482         ok(r == S_OK, "ret %08x\n", r );
2483
2484         r = IXMLDOMText_get_length(nodetext, &nLength);
2485         ok(r == S_OK, "ret %08x\n", r );
2486         ok(nLength == 2, "expected 2 got %d\n", nLength);
2487
2488         r = IXMLDOMText_get_text(nodetext, &str);
2489         ok(r == S_OK, "ret %08x\n", r );
2490         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2491         SysFreeString(str);
2492
2493         /* delete whole data ... */
2494         r = IXMLDOMText_get_length(nodetext, &nLength);
2495         ok(r == S_OK, "ret %08x\n", r );
2496
2497         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2498         ok(r == S_OK, "ret %08x\n", r );
2499         /* ... and try again with empty string */
2500         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2501         ok(r == S_OK, "ret %08x\n", r );
2502
2503         /* test put_data */
2504         V_VT(&var) = VT_BSTR;
2505         V_BSTR(&var) = SysAllocString(szstr1);
2506         r = IXMLDOMText_put_nodeValue(nodetext, var);
2507         ok(r == S_OK, "ret %08x\n", r );
2508         VariantClear(&var);
2509
2510         r = IXMLDOMText_get_text(nodetext, &str);
2511         ok(r == S_OK, "ret %08x\n", r );
2512         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2513         SysFreeString(str);
2514
2515         /* test put_data */
2516         V_VT(&var) = VT_I4;
2517         V_I4(&var) = 99;
2518         r = IXMLDOMText_put_nodeValue(nodetext, var);
2519         ok(r == S_OK, "ret %08x\n", r );
2520         VariantClear(&var);
2521
2522         r = IXMLDOMText_get_text(nodetext, &str);
2523         ok(r == S_OK, "ret %08x\n", r );
2524         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2525         SysFreeString(str);
2526
2527         /* ::replaceData() */
2528         V_VT(&var) = VT_BSTR;
2529         V_BSTR(&var) = SysAllocString(szstr1);
2530         r = IXMLDOMText_put_nodeValue(nodetext, var);
2531         ok(r == S_OK, "ret %08x\n", r );
2532         VariantClear(&var);
2533
2534         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2535         ok(r == E_INVALIDARG, "ret %08x\n", r );
2536         r = IXMLDOMText_get_text(nodetext, &str);
2537         ok(r == S_OK, "ret %08x\n", r );
2538         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2539         SysFreeString(str);
2540
2541         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2542         ok(r == S_OK, "ret %08x\n", r );
2543         r = IXMLDOMText_get_text(nodetext, &str);
2544         ok(r == S_OK, "ret %08x\n", r );
2545         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2546         SysFreeString(str);
2547
2548         /* NULL pointer means delete */
2549         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2550         ok(r == S_OK, "ret %08x\n", r );
2551         r = IXMLDOMText_get_text(nodetext, &str);
2552         ok(r == S_OK, "ret %08x\n", r );
2553         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2554         SysFreeString(str);
2555
2556         /* empty string means delete */
2557         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2558         ok(r == S_OK, "ret %08x\n", r );
2559         r = IXMLDOMText_get_text(nodetext, &str);
2560         ok(r == S_OK, "ret %08x\n", r );
2561         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2562         SysFreeString(str);
2563
2564         /* zero count means insert */
2565         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2566         ok(r == S_OK, "ret %08x\n", r );
2567         r = IXMLDOMText_get_text(nodetext, &str);
2568         ok(r == S_OK, "ret %08x\n", r );
2569         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2570         SysFreeString(str);
2571
2572         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2573         ok(r == S_OK, "ret %08x\n", r );
2574
2575         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2576         ok(r == S_OK, "ret %08x\n", r );
2577         r = IXMLDOMText_get_text(nodetext, &str);
2578         ok(r == S_OK, "ret %08x\n", r );
2579         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2580         SysFreeString(str);
2581
2582         /* nonempty string, count greater than its length */
2583         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2584         ok(r == S_OK, "ret %08x\n", r );
2585         r = IXMLDOMText_get_text(nodetext, &str);
2586         ok(r == S_OK, "ret %08x\n", r );
2587         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2588         SysFreeString(str);
2589
2590         /* nonempty string, count less than its length */
2591         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2592         ok(r == S_OK, "ret %08x\n", r );
2593         r = IXMLDOMText_get_text(nodetext, &str);
2594         ok(r == S_OK, "ret %08x\n", r );
2595         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2596         SysFreeString(str);
2597
2598         IXMLDOMText_Release( nodetext );
2599     }
2600
2601     /* test Create Comment */
2602     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2603     ok( r == E_INVALIDARG, "returns %08x\n", r );
2604     node_comment = (IXMLDOMComment*)0x1;
2605
2606     /* empty comment */
2607     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2608     ok( r == S_OK, "returns %08x\n", r );
2609     str = (BSTR)0x1;
2610     r = IXMLDOMComment_get_data(node_comment, &str);
2611     ok( r == S_OK, "returns %08x\n", r );
2612     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2613     IXMLDOMComment_Release(node_comment);
2614     SysFreeString(str);
2615
2616     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2617     ok( r == S_OK, "returns %08x\n", r );
2618     str = (BSTR)0x1;
2619     r = IXMLDOMComment_get_data(node_comment, &str);
2620     ok( r == S_OK, "returns %08x\n", r );
2621     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2622     IXMLDOMComment_Release(node_comment);
2623     SysFreeString(str);
2624
2625     str = SysAllocString(szComment);
2626     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2627     SysFreeString(str);
2628     ok( r == S_OK, "returns %08x\n", r );
2629     if(node_comment)
2630     {
2631         /* Last Child Checks */
2632         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2633         ok(r == E_INVALIDARG, "ret %08x\n", r );
2634
2635         nodeChild = (IXMLDOMNode*)0x1;
2636         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2637         ok(r == S_FALSE, "ret %08x\n", r );
2638         ok(nodeChild == NULL, "pLastChild not NULL\n");
2639
2640         /* baseName */
2641         str = (BSTR)0xdeadbeef;
2642         IXMLDOMComment_get_baseName(node_comment, &str);
2643         ok(r == S_FALSE, "ret %08x\n", r );
2644         ok(str == NULL, "Expected NULL\n");
2645
2646         IXMLDOMComment_Release( node_comment );
2647     }
2648
2649     /* test Create Attribute */
2650     str = SysAllocString(szAttribute);
2651     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2652     ok( r == E_INVALIDARG, "returns %08x\n", r );
2653     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2654     ok( r == S_OK, "returns %08x\n", r );
2655     IXMLDOMText_Release( node_attr);
2656     SysFreeString(str);
2657
2658     /* test Processing Instruction */
2659     str = SysAllocStringLen(NULL, 0);
2660     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2661     ok( r == E_INVALIDARG, "returns %08x\n", r );
2662     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2663     ok( r == E_FAIL, "returns %08x\n", r );
2664     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2665     ok( r == E_FAIL, "returns %08x\n", r );
2666     SysFreeString(str);
2667
2668     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2669     ok( r == S_OK, "returns %08x\n", r );
2670     if(nodePI)
2671     {
2672         /* Last Child Checks */
2673         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2674         ok(r == E_INVALIDARG, "ret %08x\n", r );
2675
2676         nodeChild = (IXMLDOMNode*)0x1;
2677         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2678         ok(r == S_FALSE, "ret %08x\n", r );
2679         ok(nodeChild == NULL, "nodeChild not NULL\n");
2680
2681         /* test nodeName */
2682         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2683         ok(r == S_OK, "ret %08x\n", r );
2684         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2685         SysFreeString(str);
2686
2687         /* test baseName */
2688         str = (BSTR)0x1;
2689         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2690         ok(r == S_OK, "ret %08x\n", r );
2691         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2692         SysFreeString(str);
2693
2694         /* test Target */
2695         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2696         ok(r == S_OK, "ret %08x\n", r );
2697         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2698         SysFreeString(str);
2699
2700         /* test get_data */
2701         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2702         ok(r == S_OK, "ret %08x\n", r );
2703         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2704         SysFreeString(str);
2705
2706         /* test put_data */
2707         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2708         ok(r == E_FAIL, "ret %08x\n", r );
2709
2710         /* test put_data */
2711         V_VT(&var) = VT_BSTR;
2712         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2713         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2714         ok(r == E_FAIL, "ret %08x\n", r );
2715         VariantClear(&var);
2716
2717         /* test get nodeName */
2718         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2719         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2720         ok(r == S_OK, "ret %08x\n", r );
2721         SysFreeString(str);
2722
2723         IXMLDOMProcessingInstruction_Release(nodePI);
2724     }
2725
2726     ref = IXMLDOMDocument_Release( doc );
2727     ok( ref == 0, "got %d\n", ref);
2728
2729     free_bstrs();
2730 }
2731
2732 static void test_persiststreaminit(void)
2733 {
2734     IXMLDOMDocument *doc;
2735     IPersistStreamInit *streaminit;
2736     HRESULT hr;
2737
2738     doc = create_document(&IID_IXMLDOMDocument);
2739     if (!doc) return;
2740
2741     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2742     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2743
2744     hr = IPersistStreamInit_InitNew(streaminit);
2745     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2746
2747     IXMLDOMDocument_Release(doc);
2748 }
2749
2750 static void test_domnode( void )
2751 {
2752     HRESULT r;
2753     IXMLDOMDocument *doc, *owner = NULL;
2754     IXMLDOMElement *element = NULL;
2755     IXMLDOMNamedNodeMap *map = NULL;
2756     IXMLDOMNode *node = NULL, *next = NULL;
2757     IXMLDOMNodeList *list = NULL;
2758     IXMLDOMAttribute *attr = NULL;
2759     DOMNodeType type = NODE_INVALID;
2760     VARIANT_BOOL b;
2761     BSTR str;
2762     VARIANT var;
2763     LONG count;
2764
2765     doc = create_document(&IID_IXMLDOMDocument);
2766     if (!doc) return;
2767
2768     b = FALSE;
2769     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2770     ok( r == S_OK, "loadXML failed\n");
2771     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2772
2773     EXPECT_CHILDREN(doc);
2774
2775     r = IXMLDOMDocument_get_documentElement( doc, &element );
2776     ok( r == S_OK, "should be a document element\n");
2777     ok( element != NULL, "should be an element\n");
2778
2779     VariantInit(&var);
2780     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2781
2782     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2783     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2784
2785     r = IXMLDOMNode_get_nodeValue( doc, &var );
2786     ok( r == S_FALSE, "nextNode returned wrong code\n");
2787     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2788     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2789
2790     if (element)
2791     {
2792         owner = NULL;
2793         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2794         ok( r == S_OK, "get_ownerDocument return code\n");
2795         ok( owner != doc, "get_ownerDocument return\n");
2796         IXMLDOMDocument_Release(owner);
2797
2798         type = NODE_INVALID;
2799         r = IXMLDOMNode_get_nodeType( element, &type);
2800         ok( r == S_OK, "got %08x\n", r);
2801         ok( type == NODE_ELEMENT, "node not an element\n");
2802
2803         str = NULL;
2804         r = IXMLDOMNode_get_baseName( element, &str );
2805         ok( r == S_OK, "get_baseName returned wrong code\n");
2806         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2807         SysFreeString(str);
2808
2809         /* check if nodename is correct */
2810         r = IXMLDOMElement_get_nodeName( element, NULL );
2811         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2812
2813         /* content doesn't matter here */
2814         str = NULL;
2815         r = IXMLDOMElement_get_nodeName( element, &str );
2816         ok ( r == S_OK, "get_nodeName wrong code\n");
2817         ok ( str != NULL, "str is null\n");
2818         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2819         SysFreeString( str );
2820
2821         str = SysAllocString( nonexistent_fileW );
2822         V_VT(&var) = VT_I4;
2823         V_I4(&var) = 0x1234;
2824         r = IXMLDOMElement_getAttribute( element, str, &var );
2825         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2826         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2827         VariantClear(&var);
2828
2829         str = SysAllocString( szdl );   
2830         V_VT(&var) = VT_I4;
2831         V_I4(&var) = 0x1234;
2832         r = IXMLDOMElement_getAttribute( element, str, &var );
2833         ok( r == S_OK, "getAttribute ret %08x\n", r );
2834         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2835         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2836         VariantClear( &var );
2837
2838         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2839         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2840
2841         r = IXMLDOMElement_getAttribute( element, str, NULL );
2842         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2843
2844         attr = NULL;
2845         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2846         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2847         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2848         if (attr)
2849         {
2850             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2851             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2852
2853             /* attribute doesn't have a parent in msxml interpretation */
2854             node = (IXMLDOMNode*)0xdeadbeef;
2855             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2856             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2857             ok( node == NULL, "Expected NULL, got %p\n", node );
2858
2859             IXMLDOMAttribute_Release(attr);
2860         }
2861
2862         SysFreeString( str );
2863
2864         r = IXMLDOMElement_get_attributes( element, &map );
2865         ok( r == S_OK, "get_attributes returned wrong code\n");
2866         ok( map != NULL, "should be attributes\n");
2867
2868         EXPECT_CHILDREN(element);
2869     }
2870     else
2871         ok( FALSE, "no element\n");
2872
2873     if (map)
2874     {
2875         str = SysAllocString( szdl );
2876         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2877         ok( r == S_OK, "getNamedItem returned wrong code\n");
2878         ok( node != NULL, "should be attributes\n");
2879         IXMLDOMNode_Release(node);
2880         SysFreeString( str );
2881
2882         str = SysAllocString( szdl );
2883         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2884         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2885         SysFreeString( str );
2886
2887         /* something that isn't in complete4A */
2888         str = SysAllocString( szOpen );
2889         node = (IXMLDOMNode *) 1;
2890         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2891         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2892         ok( node == NULL, "getNamedItem should have returned NULL\n");
2893         SysFreeString( str );
2894
2895         /* test indexed access of attributes */
2896         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2897         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2898
2899         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2900         ok ( r == S_OK, "get_length wrong code\n");
2901         ok ( count == 1, "get_length != 1\n");
2902
2903         node = NULL;
2904         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2905         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2906         ok ( node == NULL, "there is no node\n");
2907
2908         node = NULL;
2909         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2910         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2911         ok ( node == NULL, "there is no attribute\n");
2912
2913         node = NULL;
2914         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2915         ok ( r == S_OK, "get_item (0) wrong code\n");
2916         ok ( node != NULL, "should be attribute\n");
2917
2918         r = IXMLDOMNode_get_nodeName( node, NULL );
2919         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2920
2921         /* content doesn't matter here */
2922         str = NULL;
2923         r = IXMLDOMNode_get_nodeName( node, &str );
2924         ok ( r == S_OK, "get_nodeName wrong code\n");
2925         ok ( str != NULL, "str is null\n");
2926         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2927         SysFreeString( str );
2928         IXMLDOMNode_Release( node );
2929
2930         /* test sequential access of attributes */
2931         node = NULL;
2932         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2933         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2934         ok ( node != NULL, "nextNode, should be attribute\n");
2935         IXMLDOMNode_Release( node );
2936
2937         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2938         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2939         ok ( node == NULL, "nextNode, there is no attribute\n");
2940
2941         r = IXMLDOMNamedNodeMap_reset( map );
2942         ok ( r == S_OK, "reset should return S_OK\n");
2943
2944         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2945         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2946         ok ( node != NULL, "nextNode, should be attribute\n");
2947     }
2948     else
2949         ok( FALSE, "no map\n");
2950
2951     if (node)
2952     {
2953         type = NODE_INVALID;
2954         r = IXMLDOMNode_get_nodeType( node, &type);
2955         ok( r == S_OK, "getNamedItem returned wrong code\n");
2956         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2957
2958         str = NULL;
2959         r = IXMLDOMNode_get_baseName( node, NULL );
2960         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2961
2962         str = NULL;
2963         r = IXMLDOMNode_get_baseName( node, &str );
2964         ok( r == S_OK, "get_baseName returned wrong code\n");
2965         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2966         SysFreeString( str );
2967
2968         r = IXMLDOMNode_get_childNodes( node, NULL );
2969         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2970
2971         r = IXMLDOMNode_get_childNodes( node, &list );
2972         ok( r == S_OK, "get_childNodes returned wrong code\n");
2973
2974         if (list)
2975         {
2976             r = IXMLDOMNodeList_nextNode( list, &next );
2977             ok( r == S_OK, "nextNode returned wrong code\n");
2978         }
2979         else
2980             ok( FALSE, "no childlist\n");
2981
2982         if (next)
2983         {
2984             EXPECT_NO_CHILDREN(next);
2985
2986             type = NODE_INVALID;
2987             r = IXMLDOMNode_get_nodeType( next, &type);
2988             ok( r == S_OK, "getNamedItem returned wrong code\n");
2989             ok( type == NODE_TEXT, "node not text\n");
2990
2991             str = (BSTR) 1;
2992             r = IXMLDOMNode_get_baseName( next, &str );
2993             ok( r == S_FALSE, "get_baseName returned wrong code\n");
2994             ok( str == NULL, "basename was wrong\n");
2995             SysFreeString(str);
2996         }
2997         else
2998             ok( FALSE, "no next\n");
2999
3000         if (next)
3001             IXMLDOMNode_Release( next );
3002         next = NULL;
3003         if (list)
3004             IXMLDOMNodeList_Release( list );
3005         list = NULL;
3006         if (node)
3007             IXMLDOMNode_Release( node );
3008     }
3009     else
3010         ok( FALSE, "no node\n");
3011     node = NULL;
3012
3013     if (map)
3014         IXMLDOMNamedNodeMap_Release( map );
3015
3016     /* now traverse the tree from the root element */
3017     if (element)
3018     {
3019         r = IXMLDOMNode_get_childNodes( element, &list );
3020         ok( r == S_OK, "get_childNodes returned wrong code\n");
3021
3022         /* using get_item for child list doesn't advance the position */
3023         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3024         expect_node(node, "E2.E2.D1");
3025         IXMLDOMNode_Release(node);
3026         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3027         expect_node(node, "E1.E2.D1");
3028         IXMLDOMNode_Release(node);
3029         ole_check(IXMLDOMNodeList_reset(list));
3030
3031         IXMLDOMNodeList_AddRef(list);
3032         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3033         ole_check(IXMLDOMNodeList_reset(list));
3034
3035         node = (void*)0xdeadbeef;
3036         str = SysAllocString(szdl);
3037         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3038         SysFreeString(str);
3039         ok( r == S_FALSE, "ret %08x\n", r );
3040         ok( node == NULL, "node %p\n", node );
3041
3042         str = SysAllocString(szbs);
3043         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3044         SysFreeString(str);
3045         ok( r == S_OK, "ret %08x\n", r );
3046         r = IXMLDOMNode_Release( node );
3047         ok( r == 0, "ret %08x\n", r );
3048     }
3049     else
3050         ok( FALSE, "no element\n");
3051
3052     if (list)
3053     {
3054         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3055         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3056
3057         r = IXMLDOMNodeList_get_length(list, NULL);
3058         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3059
3060         r = IXMLDOMNodeList_get_length( list, &count );
3061         ok( r == S_OK, "get_length returns %08x\n", r );
3062         ok( count == 4, "get_length got %d\n", count );
3063
3064         r = IXMLDOMNodeList_nextNode(list, NULL);
3065         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3066
3067         r = IXMLDOMNodeList_nextNode( list, &node );
3068         ok( r == S_OK, "nextNode returned wrong code\n");
3069     }
3070     else
3071         ok( FALSE, "no list\n");
3072
3073     if (node)
3074     {
3075         type = NODE_INVALID;
3076         r = IXMLDOMNode_get_nodeType( node, &type);
3077         ok( r == S_OK, "getNamedItem returned wrong code\n");
3078         ok( type == NODE_ELEMENT, "node not text\n");
3079
3080         r = IXMLDOMNode_hasChildNodes( node, NULL );
3081         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3082
3083         EXPECT_CHILDREN(node);
3084
3085         str = NULL;
3086         r = IXMLDOMNode_get_baseName( node, &str );
3087         ok( r == S_OK, "get_baseName returned wrong code\n");
3088         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3089         SysFreeString(str);
3090     }
3091     else
3092         ok( FALSE, "no node\n");
3093
3094     if (node)
3095         IXMLDOMNode_Release( node );
3096     if (list)
3097         IXMLDOMNodeList_Release( list );
3098     if (element)
3099         IXMLDOMElement_Release( element );
3100
3101     b = FALSE;
3102     str = SysAllocString( szComplete5 );
3103     r = IXMLDOMDocument_loadXML( doc, str, &b );
3104     ok( r == S_OK, "loadXML failed\n");
3105     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3106     SysFreeString( str );
3107
3108     EXPECT_CHILDREN(doc);
3109
3110     r = IXMLDOMDocument_get_documentElement( doc, &element );
3111     ok( r == S_OK, "should be a document element\n");
3112     ok( element != NULL, "should be an element\n");
3113
3114     if (element)
3115     {
3116         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3117         BSTR tag = NULL;
3118
3119         /* check if the tag is correct */
3120         r = IXMLDOMElement_get_tagName( element, &tag );
3121         ok( r == S_OK, "couldn't get tag name\n");
3122         ok( tag != NULL, "tag was null\n");
3123         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3124         SysFreeString( tag );
3125     }
3126
3127     if (element)
3128         IXMLDOMElement_Release( element );
3129     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3130
3131     free_bstrs();
3132 }
3133
3134 typedef struct {
3135     DOMNodeType type;
3136     REFIID iid;
3137 } refcount_test_t;
3138
3139 static const refcount_test_t refcount_test[] = {
3140     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3141     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3142     { NODE_TEXT,                   &IID_IXMLDOMText },
3143     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3144     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3145     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3146     { NODE_COMMENT,                &IID_IXMLDOMComment },
3147     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3148     { NODE_INVALID,                &IID_NULL }
3149 };
3150
3151 static void test_refs(void)
3152 {
3153     IXMLDOMImplementation *impl, *impl2;
3154     IXMLDOMElement *element, *elem2;
3155     IXMLDOMNodeList *node_list = NULL;
3156     IXMLDOMNode *node, *node2, *node3;
3157     const refcount_test_t *ptr;
3158     IXMLDOMDocument *doc;
3159     IUnknown *unk, *unk2;
3160     VARIANT_BOOL b;
3161     HRESULT hr;
3162     LONG ref;
3163
3164     doc = create_document(&IID_IXMLDOMDocument);
3165     if (!doc) return;
3166
3167     ptr = refcount_test;
3168     while (ptr->type != NODE_INVALID)
3169     {
3170         IUnknown *node_typed, *node_typed2;
3171         IDispatchEx *dispex, *dispex2;
3172         IDispatch *disp, *disp2;
3173         VARIANT type;
3174
3175         V_VT(&type) = VT_I1;
3176         V_I1(&type) = ptr->type;
3177
3178         EXPECT_REF(doc, 1);
3179         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3180         EXPECT_HR(hr, S_OK);
3181         EXPECT_REF(doc, 1);
3182         EXPECT_REF(node, 1);
3183
3184         /* try IDispatch and IUnknown from IXMLDOMNode */
3185         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3186         EXPECT_HR(hr, S_OK);
3187         EXPECT_REF(unk, 2);
3188 todo_wine {
3189         EXPECT_REF(node, 1);
3190         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3191 }
3192         EXPECT_REF(unk, 2);
3193         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3194         EXPECT_HR(hr, S_OK);
3195         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3196         EXPECT_REF(unk, 3);
3197         todo_wine EXPECT_REF(disp, 1);
3198
3199         EXPECT_REF(unk, 3);
3200         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3201         EXPECT_HR(hr, S_OK);
3202         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3203         EXPECT_REF(unk, 4);
3204         todo_wine EXPECT_REF(disp2, 1);
3205
3206         IDispatch_Release(disp);
3207         IDispatch_Release(disp2);
3208
3209         /* get IXMLDOMNode from this IUnknown */
3210         EXPECT_REF(unk, 2);
3211         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3212         EXPECT_HR(hr, S_OK);
3213         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3214         EXPECT_REF(unk, 3);
3215         todo_wine EXPECT_REF(node2, 1);
3216
3217         EXPECT_REF(unk, 3);
3218         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3219         EXPECT_HR(hr, S_OK);
3220         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3221         EXPECT_REF(unk, 4);
3222         todo_wine EXPECT_REF(node3, 1);
3223
3224         IXMLDOMNode_Release(node2);
3225         IXMLDOMNode_Release(node3);
3226
3227         /* try IDispatchEx from IUnknown */
3228         EXPECT_REF(unk, 2);
3229         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3230         EXPECT_HR(hr, S_OK);
3231         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3232         EXPECT_REF(unk, 3);
3233         todo_wine EXPECT_REF(dispex, 1);
3234
3235         EXPECT_REF(unk, 3);
3236         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3237         EXPECT_HR(hr, S_OK);
3238         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3239         EXPECT_REF(unk, 4);
3240         todo_wine EXPECT_REF(dispex2, 1);
3241
3242         IDispatch_Release(dispex);
3243         IDispatch_Release(dispex2);
3244
3245         /* try corresponding IXMLDOM* */
3246         EXPECT_REF(unk, 2);
3247         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3248         EXPECT_HR(hr, S_OK);
3249         EXPECT_REF(unk, 3);
3250         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3251         EXPECT_HR(hr, S_OK);
3252         EXPECT_REF(unk, 4);
3253         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3254         IUnknown_Release(node_typed);
3255         IUnknown_Release(node_typed2);
3256
3257         /* try invalid IXMLDOM* */
3258         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3259         EXPECT_HR(hr, E_NOINTERFACE);
3260
3261         IUnknown_Release(unk);
3262
3263         EXPECT_REF(node, 1);
3264         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3265         EXPECT_HR(hr, S_OK);
3266         EXPECT_REF(node, 2);
3267         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3268
3269         EXPECT_REF(node, 2);
3270         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3271         EXPECT_HR(hr, S_OK);
3272         EXPECT_REF(node, 3);
3273 todo_wine {
3274         EXPECT_REF(node_typed, 2);
3275         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3276 }
3277         IUnknown_Release(node_typed);
3278
3279         IXMLDOMNode_Release(node2);
3280         IXMLDOMNode_Release(node);
3281
3282         ptr++;
3283     }
3284
3285     EXPECT_REF(doc, 1);
3286     ref = IXMLDOMDocument_Release(doc);
3287     ok( ref == 0, "ref %d\n", ref);
3288
3289     /* check IUnknown after releasing DOM iface */
3290     doc = create_document(&IID_IXMLDOMDocument);
3291     EXPECT_REF(doc, 1);
3292     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3293     EXPECT_HR(hr, S_OK);
3294 todo_wine {
3295     EXPECT_REF(unk, 3);
3296     EXPECT_REF(doc, 1);
3297 }
3298     IXMLDOMDocument_Release(doc);
3299     EXPECT_REF(unk, 1);
3300     IUnknown_Release(unk);
3301
3302     doc = create_document(&IID_IXMLDOMDocument);
3303     if (!doc) return;
3304
3305     EXPECT_REF(doc, 1);
3306     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3307     EXPECT_HR(hr, S_OK);
3308 todo_wine {
3309     EXPECT_REF(unk, 3);
3310     EXPECT_REF(doc, 1);
3311 }
3312     IUnknown_Release(unk);
3313
3314     /* IXMLDOMImplementation */
3315     EXPECT_REF(doc, 1);
3316     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3317     EXPECT_HR(hr, S_OK);
3318     EXPECT_REF(doc, 1);
3319     EXPECT_REF(impl, 1);
3320     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3321     EXPECT_HR(hr, S_OK);
3322     EXPECT_REF(doc, 1);
3323     EXPECT_REF(impl2, 1);
3324     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3325     IXMLDOMImplementation_Release(impl);
3326     IXMLDOMImplementation_Release(impl2);
3327
3328     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3329     EXPECT_HR(hr, S_OK);
3330     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3331
3332     EXPECT_REF(doc, 1);
3333     IXMLDOMDocument_AddRef( doc );
3334     EXPECT_REF(doc, 2);
3335     IXMLDOMDocument_AddRef( doc );
3336     EXPECT_REF(doc, 3);
3337
3338     IXMLDOMDocument_Release( doc );
3339     IXMLDOMDocument_Release( doc );
3340
3341     EXPECT_REF(doc, 1);
3342     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3343     EXPECT_HR(hr, S_OK);
3344 todo_wine {
3345     EXPECT_REF(unk, 3);
3346     EXPECT_REF(doc, 1);
3347 }
3348     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3349     EXPECT_HR(hr, S_OK);
3350 todo_wine {
3351     EXPECT_REF(doc, 1);
3352     EXPECT_REF(element, 2);
3353 }
3354     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3355     EXPECT_HR(hr, S_OK);
3356
3357 todo_wine {
3358     EXPECT_REF(doc, 1);
3359     EXPECT_REF(element, 2);
3360     EXPECT_REF(elem2, 2);
3361 }
3362     IXMLDOMElement_AddRef(element);
3363     todo_wine EXPECT_REF(element, 3);
3364     IXMLDOMElement_Release(element);
3365
3366     /* get IUnknown from a node doesn't touch node instance refcount */
3367     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3368     EXPECT_HR(hr, S_OK);
3369     EXPECT_REF(element, 2);
3370 todo_wine {
3371     EXPECT_REF(unk, 4);
3372     EXPECT_REF(elem2, 2);
3373 }
3374     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3375     EXPECT_HR(hr, S_OK);
3376 todo_wine {
3377     EXPECT_REF(unk, 5);
3378     EXPECT_REF(unk2, 5);
3379 }
3380     EXPECT_REF(element, 2);
3381     EXPECT_REF(elem2, 2);
3382
3383     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3384
3385     IUnknown_Release(unk);
3386     IUnknown_Release(unk2);
3387
3388     /* IUnknown refcount is not affected by node refcount */
3389     todo_wine EXPECT_REF(unk2, 3);
3390     IXMLDOMElement_AddRef(elem2);
3391     todo_wine EXPECT_REF(unk2, 3);
3392     IXMLDOMElement_Release(elem2);
3393
3394     IXMLDOMElement_Release(elem2);
3395     todo_wine EXPECT_REF(unk2, 2);
3396
3397     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3398     EXPECT_HR(hr, S_OK);
3399
3400     todo_wine EXPECT_REF(element, 2);
3401     EXPECT_REF(node_list, 1);
3402
3403     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3404     EXPECT_HR(hr, S_OK);
3405     EXPECT_REF(node_list, 1);
3406     EXPECT_REF(node, 1);
3407
3408     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3409     EXPECT_HR(hr, S_OK);
3410     EXPECT_REF(node_list, 1);
3411     EXPECT_REF(node2, 1);
3412
3413     ref = IXMLDOMNode_Release( node );
3414     ok( ref == 0, "ref %d\n", ref );
3415     ref = IXMLDOMNode_Release( node2 );
3416     ok( ref == 0, "ref %d\n", ref );
3417
3418     ref = IXMLDOMNodeList_Release( node_list );
3419     ok( ref == 0, "ref %d\n", ref );
3420
3421     ok( node != node2, "node %p node2 %p\n", node, node2 );
3422
3423     ref = IXMLDOMDocument_Release( doc );
3424     todo_wine ok( ref == 0, "ref %d\n", ref );
3425
3426     todo_wine EXPECT_REF(element, 2);
3427
3428     /* IUnknown must be unique however we obtain it */
3429     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3430     EXPECT_HR(hr, S_OK);
3431     EXPECT_REF(element, 2);
3432     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3433     EXPECT_HR(hr, S_OK);
3434     todo_wine EXPECT_REF(element, 2);
3435     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3436     EXPECT_HR(hr, S_OK);
3437     todo_wine EXPECT_REF(element, 2);
3438     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3439     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3440
3441     IUnknown_Release( unk2 );
3442     IUnknown_Release( unk );
3443     IXMLDOMNode_Release( node );
3444     todo_wine EXPECT_REF(element, 2);
3445
3446     IXMLDOMElement_Release( element );
3447
3448     free_bstrs();
3449 }
3450
3451 static void test_create(void)
3452 {
3453     static const WCHAR szOne[] = {'1',0};
3454     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3455     HRESULT r;
3456     VARIANT var;
3457     BSTR str, name;
3458     IXMLDOMDocument *doc;
3459     IXMLDOMElement *element;
3460     IXMLDOMComment *comment;
3461     IXMLDOMText *text;
3462     IXMLDOMCDATASection *cdata;
3463     IXMLDOMNode *root, *node, *child;
3464     IXMLDOMNamedNodeMap *attr_map;
3465     IUnknown *unk;
3466     LONG ref;
3467     LONG num;
3468
3469     doc = create_document(&IID_IXMLDOMDocument);
3470     if (!doc) return;
3471
3472     EXPECT_REF(doc, 1);
3473
3474     /* types not supported for creation */
3475     V_VT(&var) = VT_I1;
3476     V_I1(&var) = NODE_DOCUMENT;
3477     node = (IXMLDOMNode*)0x1;
3478     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3479     ok( r == E_INVALIDARG, "returns %08x\n", r );
3480     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3481
3482     V_VT(&var) = VT_I1;
3483     V_I1(&var) = NODE_DOCUMENT_TYPE;
3484     node = (IXMLDOMNode*)0x1;
3485     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3486     ok( r == E_INVALIDARG, "returns %08x\n", r );
3487     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3488
3489     V_VT(&var) = VT_I1;
3490     V_I1(&var) = NODE_ENTITY;
3491     node = (IXMLDOMNode*)0x1;
3492     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3493     ok( r == E_INVALIDARG, "returns %08x\n", r );
3494     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3495
3496     V_VT(&var) = VT_I1;
3497     V_I1(&var) = NODE_NOTATION;
3498     node = (IXMLDOMNode*)0x1;
3499     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3500     ok( r == E_INVALIDARG, "returns %08x\n", r );
3501     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3502
3503     /* NODE_COMMENT */
3504     V_VT(&var) = VT_I1;
3505     V_I1(&var) = NODE_COMMENT;
3506     node = NULL;
3507     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3508     ok( r == S_OK, "returns %08x\n", r );
3509     ok( node != NULL, "\n");
3510
3511     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3512     ok( r == S_OK, "returns %08x\n", r );
3513     IXMLDOMNode_Release(node);
3514
3515     str = NULL;
3516     r = IXMLDOMComment_get_data(comment, &str);
3517     ok( r == S_OK, "returns %08x\n", r );
3518     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3519     IXMLDOMComment_Release(comment);
3520     SysFreeString(str);
3521
3522     node = (IXMLDOMNode*)0x1;
3523     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3524     ok( r == S_OK, "returns %08x\n", r );
3525
3526     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3527     ok( r == S_OK, "returns %08x\n", r );
3528     IXMLDOMNode_Release(node);
3529
3530     str = NULL;
3531     r = IXMLDOMComment_get_data(comment, &str);
3532     ok( r == S_OK, "returns %08x\n", r );
3533     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3534     IXMLDOMComment_Release(comment);
3535     SysFreeString(str);
3536
3537     node = (IXMLDOMNode*)0x1;
3538     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3539     ok( r == S_OK, "returns %08x\n", r );
3540
3541     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3542     ok( r == S_OK, "returns %08x\n", r );
3543     IXMLDOMNode_Release(node);
3544
3545     str = NULL;
3546     r = IXMLDOMComment_get_data(comment, &str);
3547     ok( r == S_OK, "returns %08x\n", r );
3548     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3549     IXMLDOMComment_Release(comment);
3550     SysFreeString(str);
3551
3552     /* NODE_TEXT */
3553     V_VT(&var) = VT_I1;
3554     V_I1(&var) = NODE_TEXT;
3555     node = NULL;
3556     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3557     ok( r == S_OK, "returns %08x\n", r );
3558     ok( node != NULL, "\n");
3559
3560     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3561     ok( r == S_OK, "returns %08x\n", r );
3562     IXMLDOMNode_Release(node);
3563
3564     str = NULL;
3565     r = IXMLDOMText_get_data(text, &str);
3566     ok( r == S_OK, "returns %08x\n", r );
3567     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3568     IXMLDOMText_Release(text);
3569     SysFreeString(str);
3570
3571     node = (IXMLDOMNode*)0x1;
3572     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3573     ok( r == S_OK, "returns %08x\n", r );
3574
3575     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3576     ok( r == S_OK, "returns %08x\n", r );
3577     IXMLDOMNode_Release(node);
3578
3579     str = NULL;
3580     r = IXMLDOMText_get_data(text, &str);
3581     ok( r == S_OK, "returns %08x\n", r );
3582     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3583     IXMLDOMText_Release(text);
3584     SysFreeString(str);
3585
3586     node = (IXMLDOMNode*)0x1;
3587     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3588     ok( r == S_OK, "returns %08x\n", r );
3589
3590     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3591     ok( r == S_OK, "returns %08x\n", r );
3592     IXMLDOMNode_Release(node);
3593
3594     str = NULL;
3595     r = IXMLDOMText_get_data(text, &str);
3596     ok( r == S_OK, "returns %08x\n", r );
3597     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3598     IXMLDOMText_Release(text);
3599     SysFreeString(str);
3600
3601     /* NODE_CDATA_SECTION */
3602     V_VT(&var) = VT_I1;
3603     V_I1(&var) = NODE_CDATA_SECTION;
3604     node = NULL;
3605     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3606     ok( r == S_OK, "returns %08x\n", r );
3607     ok( node != NULL, "\n");
3608
3609     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3610     ok( r == S_OK, "returns %08x\n", r );
3611     IXMLDOMNode_Release(node);
3612
3613     str = NULL;
3614     r = IXMLDOMCDATASection_get_data(cdata, &str);
3615     ok( r == S_OK, "returns %08x\n", r );
3616     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3617     IXMLDOMCDATASection_Release(cdata);
3618     SysFreeString(str);
3619
3620     node = (IXMLDOMNode*)0x1;
3621     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3622     ok( r == S_OK, "returns %08x\n", r );
3623
3624     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3625     ok( r == S_OK, "returns %08x\n", r );
3626     IXMLDOMNode_Release(node);
3627
3628     str = NULL;
3629     r = IXMLDOMCDATASection_get_data(cdata, &str);
3630     ok( r == S_OK, "returns %08x\n", r );
3631     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3632     IXMLDOMCDATASection_Release(cdata);
3633     SysFreeString(str);
3634
3635     node = (IXMLDOMNode*)0x1;
3636     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3637     ok( r == S_OK, "returns %08x\n", r );
3638
3639     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3640     ok( r == S_OK, "returns %08x\n", r );
3641     IXMLDOMNode_Release(node);
3642
3643     str = NULL;
3644     r = IXMLDOMCDATASection_get_data(cdata, &str);
3645     ok( r == S_OK, "returns %08x\n", r );
3646     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3647     IXMLDOMCDATASection_Release(cdata);
3648     SysFreeString(str);
3649
3650     /* NODE_ATTRIBUTE */
3651     V_VT(&var) = VT_I1;
3652     V_I1(&var) = NODE_ATTRIBUTE;
3653     node = (IXMLDOMNode*)0x1;
3654     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3655     ok( r == E_FAIL, "returns %08x\n", r );
3656     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3657
3658     V_VT(&var) = VT_I1;
3659     V_I1(&var) = NODE_ATTRIBUTE;
3660     node = (IXMLDOMNode*)0x1;
3661     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3662     ok( r == E_FAIL, "returns %08x\n", r );
3663     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3664
3665     V_VT(&var) = VT_I1;
3666     V_I1(&var) = NODE_ATTRIBUTE;
3667     str = SysAllocString( szlc );
3668     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3669     ok( r == S_OK, "returns %08x\n", r );
3670     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3671     SysFreeString(str);
3672
3673     /* a name is required for attribute, try a BSTR with first null wchar */
3674     V_VT(&var) = VT_I1;
3675     V_I1(&var) = NODE_ATTRIBUTE;
3676     str = SysAllocString( szstr1 );
3677     str[0] = 0;
3678     node = (IXMLDOMNode*)0x1;
3679     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3680     ok( r == E_FAIL, "returns %08x\n", r );
3681     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3682     SysFreeString(str);
3683
3684     /* NODE_PROCESSING_INSTRUCTION */
3685     V_VT(&var) = VT_I1;
3686     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3687     node = (IXMLDOMNode*)0x1;
3688     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3689     ok( r == E_FAIL, "returns %08x\n", r );
3690     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3691
3692     V_VT(&var) = VT_I1;
3693     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3694     node = (IXMLDOMNode*)0x1;
3695     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3696     ok( r == E_FAIL, "returns %08x\n", r );
3697     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3698
3699     V_VT(&var) = VT_I1;
3700     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3701     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3702     ok( r == E_INVALIDARG, "returns %08x\n", r );
3703
3704     /* NODE_ENTITY_REFERENCE */
3705     V_VT(&var) = VT_I1;
3706     V_I1(&var) = NODE_ENTITY_REFERENCE;
3707     node = (IXMLDOMNode*)0x1;
3708     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3709     ok( r == E_FAIL, "returns %08x\n", r );
3710     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3711
3712     V_VT(&var) = VT_I1;
3713     V_I1(&var) = NODE_ENTITY_REFERENCE;
3714     node = (IXMLDOMNode*)0x1;
3715     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3716     ok( r == E_FAIL, "returns %08x\n", r );
3717     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3718
3719     /* NODE_ELEMENT */
3720     V_VT(&var) = VT_I1;
3721     V_I1(&var) = NODE_ELEMENT;
3722     node = (IXMLDOMNode*)0x1;
3723     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3724     ok( r == E_FAIL, "returns %08x\n", r );
3725     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3726
3727     V_VT(&var) = VT_I1;
3728     V_I1(&var) = NODE_ELEMENT;
3729     node = (IXMLDOMNode*)0x1;
3730     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3731     ok( r == E_FAIL, "returns %08x\n", r );
3732     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3733
3734     V_VT(&var) = VT_I1;
3735     V_I1(&var) = NODE_ELEMENT;
3736     str = SysAllocString( szlc );
3737     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3738     ok( r == S_OK, "returns %08x\n", r );
3739     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3740
3741     V_VT(&var) = VT_I1;
3742     V_I1(&var) = NODE_ELEMENT;
3743     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3744     ok( r == E_INVALIDARG, "returns %08x\n", r );
3745
3746     V_VT(&var) = VT_R4;
3747     V_R4(&var) = NODE_ELEMENT;
3748     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3749     ok( r == S_OK, "returns %08x\n", r );
3750     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3751
3752     V_VT(&var) = VT_BSTR;
3753     V_BSTR(&var) = SysAllocString( szOne );
3754     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3755     ok( r == S_OK, "returns %08x\n", r );
3756     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3757     VariantClear(&var);
3758
3759     V_VT(&var) = VT_BSTR;
3760     V_BSTR(&var) = SysAllocString( szOneGarbage );
3761     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3762     ok( r == E_INVALIDARG, "returns %08x\n", r );
3763     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3764     VariantClear(&var);
3765
3766     V_VT(&var) = VT_I4;
3767     V_I4(&var) = NODE_ELEMENT;
3768     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3769     ok( r == S_OK, "returns %08x\n", r );
3770
3771     EXPECT_REF(doc, 1);
3772     r = IXMLDOMDocument_appendChild( doc, node, &root );
3773     ok( r == S_OK, "returns %08x\n", r );
3774     ok( node == root, "%p %p\n", node, root );
3775     EXPECT_REF(doc, 1);
3776
3777     EXPECT_REF(node, 2);
3778
3779     ref = IXMLDOMNode_Release( node );
3780     ok(ref == 1, "ref %d\n", ref);
3781     SysFreeString( str );
3782
3783     V_VT(&var) = VT_I4;
3784     V_I4(&var) = NODE_ELEMENT;
3785     str = SysAllocString( szbs );
3786     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3787     ok( r == S_OK, "returns %08x\n", r );
3788     SysFreeString( str );
3789
3790     EXPECT_REF(node, 1);
3791
3792     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3793     ok( r == S_OK, "returns %08x\n", r );
3794
3795     EXPECT_REF(unk, 2);
3796
3797     V_VT(&var) = VT_EMPTY;
3798     child = NULL;
3799     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3800     ok( r == S_OK, "returns %08x\n", r );
3801     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3802
3803     todo_wine EXPECT_REF(unk, 4);
3804
3805     IXMLDOMNode_Release( child );
3806     IUnknown_Release( unk );
3807
3808     V_VT(&var) = VT_NULL;
3809     V_DISPATCH(&var) = (IDispatch*)node;
3810     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3811     ok( r == S_OK, "returns %08x\n", r );
3812     ok( node == child, "%p %p\n", node, child );
3813     IXMLDOMNode_Release( child );
3814
3815     V_VT(&var) = VT_NULL;
3816     V_DISPATCH(&var) = (IDispatch*)node;
3817     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3818     ok( r == S_OK, "returns %08x\n", r );
3819     IXMLDOMNode_Release( node );
3820
3821     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3822     ok( r == S_OK, "returns %08x\n", r );
3823
3824     r = IXMLDOMElement_get_attributes( element, &attr_map );
3825     ok( r == S_OK, "returns %08x\n", r );
3826     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3827     ok( r == S_OK, "returns %08x\n", r );
3828     ok( num == 0, "num %d\n", num );
3829     IXMLDOMNamedNodeMap_Release( attr_map );
3830
3831     V_VT(&var) = VT_BSTR;
3832     V_BSTR(&var) = SysAllocString( szstr1 );
3833     name = SysAllocString( szdl );
3834     r = IXMLDOMElement_setAttribute( element, name, var );
3835     ok( r == S_OK, "returns %08x\n", r );
3836     r = IXMLDOMElement_get_attributes( element, &attr_map );
3837     ok( r == S_OK, "returns %08x\n", r );
3838     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3839     ok( r == S_OK, "returns %08x\n", r );
3840     ok( num == 1, "num %d\n", num );
3841     IXMLDOMNamedNodeMap_Release( attr_map );
3842     VariantClear(&var);
3843
3844     V_VT(&var) = VT_BSTR;
3845     V_BSTR(&var) = SysAllocString( szstr2 );
3846     r = IXMLDOMElement_setAttribute( element, name, var );
3847     ok( r == S_OK, "returns %08x\n", r );
3848     r = IXMLDOMElement_get_attributes( element, &attr_map );
3849     ok( r == S_OK, "returns %08x\n", r );
3850     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3851     ok( r == S_OK, "returns %08x\n", r );
3852     ok( num == 1, "num %d\n", num );
3853     IXMLDOMNamedNodeMap_Release( attr_map );
3854     VariantClear(&var);
3855     r = IXMLDOMElement_getAttribute( element, name, &var );
3856     ok( r == S_OK, "returns %08x\n", r );
3857     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3858     VariantClear(&var);
3859     SysFreeString(name);
3860
3861     V_VT(&var) = VT_BSTR;
3862     V_BSTR(&var) = SysAllocString( szstr1 );
3863     name = SysAllocString( szlc );
3864     r = IXMLDOMElement_setAttribute( element, name, var );
3865     ok( r == S_OK, "returns %08x\n", r );
3866     r = IXMLDOMElement_get_attributes( element, &attr_map );
3867     ok( r == S_OK, "returns %08x\n", r );
3868     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3869     ok( r == S_OK, "returns %08x\n", r );
3870     ok( num == 2, "num %d\n", num );
3871     IXMLDOMNamedNodeMap_Release( attr_map );
3872     VariantClear(&var);
3873     SysFreeString(name);
3874
3875     V_VT(&var) = VT_I4;
3876     V_I4(&var) = 10;
3877     name = SysAllocString( szbs );
3878     r = IXMLDOMElement_setAttribute( element, name, var );
3879     ok( r == S_OK, "returns %08x\n", r );
3880     VariantClear(&var);
3881     r = IXMLDOMElement_getAttribute( element, name, &var );
3882     ok( r == S_OK, "returns %08x\n", r );
3883     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3884     VariantClear(&var);
3885     SysFreeString(name);
3886
3887     /* Create an Attribute */
3888     V_VT(&var) = VT_I4;
3889     V_I4(&var) = NODE_ATTRIBUTE;
3890     str = SysAllocString( szAttribute );
3891     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3892     ok( r == S_OK, "returns %08x\n", r );
3893     ok( node != NULL, "node was null\n");
3894     SysFreeString(str);
3895
3896     IXMLDOMElement_Release( element );
3897     IXMLDOMNode_Release( root );
3898     IXMLDOMDocument_Release( doc );
3899 }
3900
3901 static void test_getElementsByTagName(void)
3902 {
3903     IXMLDOMNodeList *node_list;
3904     IXMLDOMDocument *doc;
3905     IXMLDOMElement *elem;
3906     WCHAR buff[100];
3907     VARIANT_BOOL b;
3908     HRESULT r;
3909     LONG len;
3910     BSTR str;
3911
3912     doc = create_document(&IID_IXMLDOMDocument);
3913     if (!doc) return;
3914
3915     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3916     ok( r == S_OK, "loadXML failed\n");
3917     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3918
3919     str = SysAllocString( szstar );
3920
3921     /* null arguments cases */
3922     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3923     ok( r == E_INVALIDARG, "ret %08x\n", r );
3924     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3925     ok( r == E_INVALIDARG, "ret %08x\n", r );
3926
3927     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3928     ok( r == S_OK, "ret %08x\n", r );
3929     r = IXMLDOMNodeList_get_length( node_list, &len );
3930     ok( r == S_OK, "ret %08x\n", r );
3931     ok( len == 6, "len %d\n", len );
3932
3933     IXMLDOMNodeList_Release( node_list );
3934     SysFreeString( str );
3935
3936     /* broken query BSTR */
3937     memcpy(&buff[2], szstar, sizeof(szstar));
3938     /* just a big length */
3939     *(DWORD*)buff = 0xf0f0;
3940     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3941     ok( r == S_OK, "ret %08x\n", r );
3942     r = IXMLDOMNodeList_get_length( node_list, &len );
3943     ok( r == S_OK, "ret %08x\n", r );
3944     ok( len == 6, "len %d\n", len );
3945     IXMLDOMNodeList_Release( node_list );
3946
3947     str = SysAllocString( szbs );
3948     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3949     ok( r == S_OK, "ret %08x\n", r );
3950     r = IXMLDOMNodeList_get_length( node_list, &len );
3951     ok( r == S_OK, "ret %08x\n", r );
3952     ok( len == 1, "len %d\n", len );
3953     IXMLDOMNodeList_Release( node_list );
3954     SysFreeString( str );
3955
3956     str = SysAllocString( szdl );
3957     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3958     ok( r == S_OK, "ret %08x\n", r );
3959     r = IXMLDOMNodeList_get_length( node_list, &len );
3960     ok( r == S_OK, "ret %08x\n", r );
3961     ok( len == 0, "len %d\n", len );
3962     IXMLDOMNodeList_Release( node_list );
3963     SysFreeString( str );
3964
3965     str = SysAllocString( szstr1 );
3966     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3967     ok( r == S_OK, "ret %08x\n", r );
3968     r = IXMLDOMNodeList_get_length( node_list, &len );
3969     ok( r == S_OK, "ret %08x\n", r );
3970     ok( len == 0, "len %d\n", len );
3971     IXMLDOMNodeList_Release( node_list );
3972     SysFreeString( str );
3973
3974     /* test for element */
3975     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3976     ok( r == S_OK, "ret %08x\n", r );
3977
3978     str = SysAllocString( szstar );
3979
3980     /* null arguments cases */
3981     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3982     ok( r == E_INVALIDARG, "ret %08x\n", r );
3983     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3984     ok( r == E_INVALIDARG, "ret %08x\n", r );
3985
3986     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3987     ok( r == S_OK, "ret %08x\n", r );
3988     r = IXMLDOMNodeList_get_length( node_list, &len );
3989     ok( r == S_OK, "ret %08x\n", r );
3990     ok( len == 5, "len %d\n", len );
3991     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3992     SysFreeString( str );
3993
3994     /* broken query BSTR */
3995     memcpy(&buff[2], szstar, sizeof(szstar));
3996     /* just a big length */
3997     *(DWORD*)buff = 0xf0f0;
3998     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3999     ok( r == S_OK, "ret %08x\n", r );
4000     r = IXMLDOMNodeList_get_length( node_list, &len );
4001     ok( r == S_OK, "ret %08x\n", r );
4002     ok( len == 5, "len %d\n", len );
4003     IXMLDOMNodeList_Release( node_list );
4004
4005     IXMLDOMElement_Release(elem);
4006
4007     IXMLDOMDocument_Release( doc );
4008
4009     free_bstrs();
4010 }
4011
4012 static void test_get_text(void)
4013 {
4014     HRESULT r;
4015     BSTR str;
4016     VARIANT_BOOL b;
4017     IXMLDOMDocument *doc;
4018     IXMLDOMNode *node, *node2, *node3;
4019     IXMLDOMNode *nodeRoot;
4020     IXMLDOMNodeList *node_list;
4021     IXMLDOMNamedNodeMap *node_map;
4022     LONG len;
4023
4024     doc = create_document(&IID_IXMLDOMDocument);
4025     if (!doc) return;
4026
4027     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4028     ok( r == S_OK, "loadXML failed\n");
4029     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4030
4031     str = SysAllocString( szbs );
4032     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
4033     ok( r == S_OK, "ret %08x\n", r );
4034     SysFreeString(str);
4035
4036     /* Test to get all child node text. */
4037     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
4038     ok( r == S_OK, "ret %08x\n", r );
4039     if(r == S_OK)
4040     {
4041         r = IXMLDOMNode_get_text( nodeRoot, &str );
4042         ok( r == S_OK, "ret %08x\n", r );
4043         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
4044         SysFreeString(str);
4045
4046         IXMLDOMNode_Release(nodeRoot);
4047     }
4048
4049     r = IXMLDOMNodeList_get_length( node_list, NULL );
4050     ok( r == E_INVALIDARG, "ret %08x\n", r );
4051
4052     r = IXMLDOMNodeList_get_length( node_list, &len );
4053     ok( r == S_OK, "ret %08x\n", r );
4054     ok( len == 1, "expect 1 got %d\n", len );
4055
4056     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
4057     ok( r == E_INVALIDARG, "ret %08x\n", r );
4058
4059     r = IXMLDOMNodeList_nextNode( node_list, NULL );
4060     ok( r == E_INVALIDARG, "ret %08x\n", r );
4061
4062     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4063     ok( r == S_OK, "ret %08x\n", r );
4064     IXMLDOMNodeList_Release( node_list );
4065
4066     /* Invalid output parameter*/
4067     r = IXMLDOMNode_get_text( node, NULL );
4068     ok( r == E_INVALIDARG, "ret %08x\n", r );
4069
4070     r = IXMLDOMNode_get_text( node, &str );
4071     ok( r == S_OK, "ret %08x\n", r );
4072     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4073     SysFreeString(str);
4074
4075     r = IXMLDOMNode_get_attributes( node, &node_map );
4076     ok( r == S_OK, "ret %08x\n", r );
4077
4078     str = SysAllocString( szvr );
4079     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4080     ok( r == S_OK, "ret %08x\n", r );
4081     SysFreeString(str);
4082
4083     r = IXMLDOMNode_get_text( node2, &str );
4084     ok( r == S_OK, "ret %08x\n", r );
4085     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4086     SysFreeString(str);
4087
4088     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4089     ok( r == S_OK, "ret %08x\n", r );
4090
4091     r = IXMLDOMNode_get_text( node3, &str );
4092     ok( r == S_OK, "ret %08x\n", r );
4093     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4094     SysFreeString(str);
4095
4096
4097     IXMLDOMNode_Release( node3 );
4098     IXMLDOMNode_Release( node2 );
4099     IXMLDOMNamedNodeMap_Release( node_map );
4100     IXMLDOMNode_Release( node );
4101     IXMLDOMDocument_Release( doc );
4102
4103     free_bstrs();
4104 }
4105
4106 static void test_get_childNodes(void)
4107 {
4108     BSTR str;
4109     VARIANT_BOOL b;
4110     IXMLDOMDocument *doc;
4111     IXMLDOMElement *element;
4112     IXMLDOMNode *node, *node2;
4113     IXMLDOMNodeList *node_list, *node_list2;
4114     HRESULT hr;
4115     LONG len;
4116
4117     doc = create_document(&IID_IXMLDOMDocument);
4118     if (!doc) return;
4119
4120     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4121     EXPECT_HR(hr, S_OK);
4122     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4123
4124     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4125     EXPECT_HR(hr, S_OK);
4126
4127     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4128     EXPECT_HR(hr, S_OK);
4129
4130     hr = IXMLDOMNodeList_get_length( node_list, &len );
4131     EXPECT_HR(hr, S_OK);
4132     ok( len == 4, "len %d\n", len);
4133
4134     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4135     EXPECT_HR(hr, S_OK);
4136
4137     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4138     EXPECT_HR(hr, S_OK);
4139
4140     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4141     EXPECT_HR(hr, S_OK);
4142     ok( len == 0, "len %d\n", len);
4143
4144     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4145     EXPECT_HR(hr, S_FALSE);
4146
4147     IXMLDOMNodeList_Release( node_list2 );
4148     IXMLDOMNode_Release( node );
4149     IXMLDOMNodeList_Release( node_list );
4150     IXMLDOMElement_Release( element );
4151
4152     /* test for children of <?xml ..?> node */
4153     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4154     EXPECT_HR(hr, S_OK);
4155
4156     str = NULL;
4157     hr = IXMLDOMNode_get_nodeName(node, &str);
4158     EXPECT_HR(hr, S_OK);
4159     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4160     SysFreeString(str);
4161
4162     /* it returns empty but valid node list */
4163     node_list = (void*)0xdeadbeef;
4164     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4165     EXPECT_HR(hr, S_OK);
4166
4167     len = -1;
4168     hr = IXMLDOMNodeList_get_length(node_list, &len);
4169     EXPECT_HR(hr, S_OK);
4170     ok(len == 0, "got %d\n", len);
4171
4172     IXMLDOMNodeList_Release( node_list );
4173     IXMLDOMNode_Release(node);
4174
4175     IXMLDOMDocument_Release( doc );
4176     free_bstrs();
4177 }
4178
4179 static void test_get_firstChild(void)
4180 {
4181     static WCHAR xmlW[] = {'x','m','l',0};
4182     IXMLDOMDocument *doc;
4183     IXMLDOMNode *node;
4184     VARIANT_BOOL b;
4185     HRESULT r;
4186     BSTR str;
4187
4188     doc = create_document(&IID_IXMLDOMDocument);
4189     if (!doc) return;
4190
4191     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4192     ok( r == S_OK, "loadXML failed\n");
4193     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4194
4195     r = IXMLDOMDocument_get_firstChild( doc, &node );
4196     ok( r == S_OK, "ret %08x\n", r);
4197
4198     r = IXMLDOMNode_get_nodeName( node, &str );
4199     ok( r == S_OK, "ret %08x\n", r);
4200
4201     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4202
4203     SysFreeString(str);
4204     IXMLDOMNode_Release( node );
4205     IXMLDOMDocument_Release( doc );
4206
4207     free_bstrs();
4208 }
4209
4210 static void test_get_lastChild(void)
4211 {
4212     static WCHAR lcW[] = {'l','c',0};
4213     static WCHAR foW[] = {'f','o',0};
4214     IXMLDOMDocument *doc;
4215     IXMLDOMNode *node, *child;
4216     VARIANT_BOOL b;
4217     HRESULT r;
4218     BSTR str;
4219
4220     doc = create_document(&IID_IXMLDOMDocument);
4221     if (!doc) return;
4222
4223     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4224     ok( r == S_OK, "loadXML failed\n");
4225     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4226
4227     r = IXMLDOMDocument_get_lastChild( doc, &node );
4228     ok( r == S_OK, "ret %08x\n", r);
4229
4230     r = IXMLDOMNode_get_nodeName( node, &str );
4231     ok( r == S_OK, "ret %08x\n", r);
4232
4233     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4234     SysFreeString(str);
4235
4236     r = IXMLDOMNode_get_lastChild( node, &child );
4237     ok( r == S_OK, "ret %08x\n", r);
4238
4239     r = IXMLDOMNode_get_nodeName( child, &str );
4240     ok( r == S_OK, "ret %08x\n", r);
4241
4242     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4243     SysFreeString(str);
4244
4245     IXMLDOMNode_Release( child );
4246     IXMLDOMNode_Release( node );
4247     IXMLDOMDocument_Release( doc );
4248
4249     free_bstrs();
4250 }
4251
4252 static void test_removeChild(void)
4253 {
4254     HRESULT r;
4255     VARIANT_BOOL b;
4256     IXMLDOMDocument *doc;
4257     IXMLDOMElement *element, *lc_element;
4258     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4259     IXMLDOMNodeList *root_list, *fo_list;
4260
4261     doc = create_document(&IID_IXMLDOMDocument);
4262     if (!doc) return;
4263
4264     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4265     ok( r == S_OK, "loadXML failed\n");
4266     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4267
4268     r = IXMLDOMDocument_get_documentElement( doc, &element );
4269     ok( r == S_OK, "ret %08x\n", r);
4270     todo_wine EXPECT_REF(element, 2);
4271
4272     r = IXMLDOMElement_get_childNodes( element, &root_list );
4273     ok( r == S_OK, "ret %08x\n", r);
4274     EXPECT_REF(root_list, 1);
4275
4276     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4277     ok( r == S_OK, "ret %08x\n", r);
4278     EXPECT_REF(fo_node, 1);
4279
4280     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4281     ok( r == S_OK, "ret %08x\n", r);
4282     EXPECT_REF(fo_list, 1);
4283
4284     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4285     ok( r == S_OK, "ret %08x\n", r);
4286     EXPECT_REF(ba_node, 1);
4287
4288     /* invalid parameter: NULL ptr */
4289     removed_node = (void*)0xdeadbeef;
4290     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4291     ok( r == E_INVALIDARG, "ret %08x\n", r );
4292     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4293
4294     /* ba_node is a descendant of element, but not a direct child. */
4295     removed_node = (void*)0xdeadbeef;
4296     EXPECT_REF(ba_node, 1);
4297     EXPECT_CHILDREN(fo_node);
4298     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4299     ok( r == E_INVALIDARG, "ret %08x\n", r );
4300     ok( removed_node == NULL, "%p\n", removed_node );
4301     EXPECT_REF(ba_node, 1);
4302     EXPECT_CHILDREN(fo_node);
4303
4304     EXPECT_REF(ba_node, 1);
4305     EXPECT_REF(fo_node, 1);
4306     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4307     ok( r == S_OK, "ret %08x\n", r);
4308     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4309     EXPECT_REF(fo_node, 2);
4310     EXPECT_REF(ba_node, 1);
4311
4312     /* try removing already removed child */
4313     temp_node = (void*)0xdeadbeef;
4314     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4315     ok( r == E_INVALIDARG, "ret %08x\n", r);
4316     ok( temp_node == NULL, "%p\n", temp_node );
4317     IXMLDOMNode_Release( fo_node );
4318
4319     /* the removed node has no parent anymore */
4320     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4321     ok( r == S_FALSE, "ret %08x\n", r);
4322     ok( temp_node == NULL, "%p\n", temp_node );
4323
4324     IXMLDOMNode_Release( removed_node );
4325     IXMLDOMNode_Release( ba_node );
4326     IXMLDOMNodeList_Release( fo_list );
4327
4328     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4329     ok( r == S_OK, "ret %08x\n", r);
4330
4331     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4332     ok( r == S_OK, "ret %08x\n", r);
4333
4334     /* MS quirk: passing wrong interface pointer works, too */
4335     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4336     ok( r == S_OK, "ret %08x\n", r);
4337     IXMLDOMElement_Release( lc_element );
4338
4339     temp_node = (void*)0xdeadbeef;
4340     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4341     ok( r == S_FALSE, "ret %08x\n", r);
4342     ok( temp_node == NULL, "%p\n", temp_node );
4343
4344     IXMLDOMNode_Release( lc_node );
4345     IXMLDOMNodeList_Release( root_list );
4346     IXMLDOMElement_Release( element );
4347     IXMLDOMDocument_Release( doc );
4348
4349     free_bstrs();
4350 }
4351
4352 static void test_replaceChild(void)
4353 {
4354     HRESULT r;
4355     VARIANT_BOOL b;
4356     IXMLDOMDocument *doc;
4357     IXMLDOMElement *element, *ba_element;
4358     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4359     IXMLDOMNodeList *root_list, *fo_list;
4360     IUnknown * unk1, *unk2;
4361     LONG len;
4362
4363     doc = create_document(&IID_IXMLDOMDocument);
4364     if (!doc) return;
4365
4366     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4367     ok( r == S_OK, "loadXML failed\n");
4368     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4369
4370     r = IXMLDOMDocument_get_documentElement( doc, &element );
4371     ok( r == S_OK, "ret %08x\n", r);
4372
4373     r = IXMLDOMElement_get_childNodes( element, &root_list );
4374     ok( r == S_OK, "ret %08x\n", r);
4375
4376     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4377     ok( r == S_OK, "ret %08x\n", r);
4378
4379     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4380     ok( r == S_OK, "ret %08x\n", r);
4381
4382     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4383     ok( r == S_OK, "ret %08x\n", r);
4384
4385     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4386     ok( r == S_OK, "ret %08x\n", r);
4387
4388     IXMLDOMNodeList_Release( fo_list );
4389
4390     /* invalid parameter: NULL ptr for element to remove */
4391     removed_node = (void*)0xdeadbeef;
4392     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4393     ok( r == E_INVALIDARG, "ret %08x\n", r );
4394     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4395
4396     /* invalid parameter: NULL for replacement element. (Sic!) */
4397     removed_node = (void*)0xdeadbeef;
4398     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4399     ok( r == E_INVALIDARG, "ret %08x\n", r );
4400     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4401
4402     /* invalid parameter: OldNode is not a child */
4403     removed_node = (void*)0xdeadbeef;
4404     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4405     ok( r == E_INVALIDARG, "ret %08x\n", r );
4406     ok( removed_node == NULL, "%p\n", removed_node );
4407     IXMLDOMNode_Release( lc_node );
4408
4409     /* invalid parameter: would create loop */
4410     removed_node = (void*)0xdeadbeef;
4411     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4412     ok( r == E_FAIL, "ret %08x\n", r );
4413     ok( removed_node == NULL, "%p\n", removed_node );
4414
4415     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4416     ok( r == S_OK, "ret %08x\n", r );
4417
4418     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4419     ok( r == S_OK, "ret %08x\n", r );
4420
4421     /* ba_node and temp_node refer to the same node, yet they
4422        are different interface pointers */
4423     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4424     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4425     ok( r == S_OK, "ret %08x\n", r );
4426     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4427     ok( r == S_OK, "ret %08x\n", r );
4428     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4429
4430     IUnknown_Release( unk1 );
4431     IUnknown_Release( unk2 );
4432
4433     /* ba_node should have been removed from below fo_node */
4434     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4435     ok( r == S_OK, "ret %08x\n", r );
4436
4437     /* MS quirk: replaceChild also accepts elements instead of nodes */
4438     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4439     ok( r == S_OK, "ret %08x\n", r );
4440     EXPECT_REF(ba_element, 2);
4441
4442     removed_node = NULL;
4443     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4444     ok( r == S_OK, "ret %08x\n", r );
4445     ok( removed_node != NULL, "got %p\n", removed_node);
4446     EXPECT_REF(ba_element, 3);
4447     IXMLDOMElement_Release( ba_element );
4448
4449     r = IXMLDOMNodeList_get_length( fo_list, &len);
4450     ok( r == S_OK, "ret %08x\n", r );
4451     ok( len == 0, "len %d\n", len);
4452
4453     IXMLDOMNodeList_Release( fo_list );
4454
4455     IXMLDOMNode_Release(ba_node);
4456     IXMLDOMNode_Release(fo_node);
4457     IXMLDOMNode_Release(temp_node);
4458     IXMLDOMNodeList_Release( root_list );
4459     IXMLDOMElement_Release( element );
4460     IXMLDOMDocument_Release( doc );
4461
4462     free_bstrs();
4463 }
4464
4465 static void test_removeNamedItem(void)
4466 {
4467     IXMLDOMDocument *doc;
4468     IXMLDOMElement *element;
4469     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4470     IXMLDOMNodeList *root_list;
4471     IXMLDOMNamedNodeMap * pr_attrs;
4472     VARIANT_BOOL b;
4473     BSTR str;
4474     LONG len;
4475     HRESULT r;
4476
4477     doc = create_document(&IID_IXMLDOMDocument);
4478     if (!doc) return;
4479
4480     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4481     ok( r == S_OK, "loadXML failed\n");
4482     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4483
4484     r = IXMLDOMDocument_get_documentElement( doc, &element );
4485     ok( r == S_OK, "ret %08x\n", r);
4486
4487     r = IXMLDOMElement_get_childNodes( element, &root_list );
4488     ok( r == S_OK, "ret %08x\n", r);
4489
4490     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4491     ok( r == S_OK, "ret %08x\n", r);
4492
4493     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4494     ok( r == S_OK, "ret %08x\n", r);
4495
4496     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4497     ok( r == S_OK, "ret %08x\n", r);
4498     ok( len == 3, "length %d\n", len);
4499
4500     removed_node = (void*)0xdeadbeef;
4501     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4502     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4503     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4504
4505     removed_node = (void*)0xdeadbeef;
4506     str = SysAllocString(szvr);
4507     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4508     ok ( r == S_OK, "ret %08x\n", r);
4509
4510     removed_node2 = (void*)0xdeadbeef;
4511     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4512     ok ( r == S_FALSE, "ret %08x\n", r);
4513     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4514
4515     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4516     ok( r == S_OK, "ret %08x\n", r);
4517     ok( len == 2, "length %d\n", len);
4518
4519     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4520     ok ( r == S_OK, "ret %08x\n", r);
4521     IXMLDOMNode_Release(removed_node);
4522
4523     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4524     ok( r == S_OK, "ret %08x\n", r);
4525     ok( len == 3, "length %d\n", len);
4526
4527     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4528     ok ( r == S_OK, "ret %08x\n", r);
4529
4530     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4531     ok( r == S_OK, "ret %08x\n", r);
4532     ok( len == 2, "length %d\n", len);
4533
4534     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4535     ok ( r == S_FALSE, "ret %08x\n", r);
4536
4537     SysFreeString(str);
4538
4539     IXMLDOMNamedNodeMap_Release( pr_attrs );
4540     IXMLDOMNode_Release( pr_node );
4541     IXMLDOMNodeList_Release( root_list );
4542     IXMLDOMElement_Release( element );
4543     IXMLDOMDocument_Release( doc );
4544
4545     free_bstrs();
4546 }
4547
4548 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4549 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4550                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4551                                     DWORD expected2)
4552 {
4553     DWORD enabled, supported;
4554     HRESULT hr;
4555
4556     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4557     if (result == result2)
4558         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4559     else
4560         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4561            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4562
4563     supported = enabled = 0xCAFECAFE;
4564     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4565     ok(hr == S_OK, "ret %08x\n", hr );
4566     if (expected == expected2)
4567         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4568     else
4569         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4570            "Expected %08x, got %08x\n", expected2, enabled);
4571
4572     /* reset the safety options */
4573
4574     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4575             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4576             0);
4577     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4578
4579     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4580     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4581     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4582 }
4583
4584 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4585 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4586 {
4587     DWORD enabled = 0, supported = 0;
4588     HRESULT hr;
4589
4590     /* get */
4591     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4592     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4593     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4594     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4595
4596     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4597     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4598     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4599        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4600         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4601              "got %08x\n", supported);
4602     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4603
4604     /* set -- individual flags */
4605
4606     test_IObjectSafety_set(safety, S_OK, S_OK,
4607         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4608         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4609
4610     test_IObjectSafety_set(safety, S_OK, S_OK,
4611         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4612         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4613
4614     test_IObjectSafety_set(safety, S_OK, S_OK,
4615         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4616         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4617
4618     /* set INTERFACE_USES_DISPEX  */
4619
4620     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4621         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4622         0, 0);
4623
4624     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4625         INTERFACE_USES_DISPEX, 0,
4626         0, 0);
4627
4628     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4629         0, INTERFACE_USES_DISPEX,
4630         0, 0);
4631
4632     /* set option masking */
4633
4634     test_IObjectSafety_set(safety, S_OK, S_OK,
4635         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4636         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4637         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4638         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4639
4640     test_IObjectSafety_set(safety, S_OK, S_OK,
4641         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4642         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4643         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4644         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4645
4646     test_IObjectSafety_set(safety, S_OK, S_OK,
4647         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4648         INTERFACE_USES_SECURITY_MANAGER,
4649         0,
4650         0);
4651
4652     /* set -- inheriting previous settings */
4653
4654     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4655                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4656                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4657     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4658     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4659     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4660     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4661     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4662        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4663         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4664              "got %08x\n", supported);
4665
4666     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4667                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4668                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4669     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4670     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4671     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4672     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4673                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4674                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4675     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4676        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4677         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4678              "got %08x\n", supported);
4679 }
4680
4681 static void test_XMLHTTP(void)
4682 {
4683     static const char bodyA[] = "mode=Test";
4684     static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
4685     static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
4686     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4687     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4688
4689     IXMLHttpRequest *xhr;
4690     IObjectSafety *safety;
4691     IObjectWithSite *obj_site, *obj_site2;
4692     BSTR bstrResponse, str, str1;
4693     VARIANT varbody, varbody_ref;
4694     VARIANT dummy;
4695     VARIANT async;
4696     LONG state, status, bound;
4697     IDispatch *event;
4698     void *ptr;
4699     HRESULT hr;
4700     HGLOBAL g;
4701
4702     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4703         &IID_IXMLHttpRequest, (void**)&xhr);
4704     if (FAILED(hr))
4705     {
4706         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4707         return;
4708     }
4709
4710     VariantInit(&dummy);
4711     V_VT(&dummy) = VT_ERROR;
4712     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4713     VariantInit(&async);
4714     V_VT(&async) = VT_BOOL;
4715     V_BOOL(&async) = VARIANT_FALSE;
4716
4717     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4718     EXPECT_HR(hr, S_OK);
4719
4720     hr = IXMLHttpRequest_abort(xhr);
4721     EXPECT_HR(hr, S_OK);
4722
4723     V_VT(&varbody) = VT_I2;
4724     V_I2(&varbody) = 1;
4725     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4726     EXPECT_HR(hr, E_PENDING);
4727     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4728     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4729
4730     V_VT(&varbody) = VT_I2;
4731     V_I2(&varbody) = 1;
4732     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4733     EXPECT_HR(hr, E_PENDING);
4734     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4735     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4736
4737     /* send before open */
4738     hr = IXMLHttpRequest_send(xhr, dummy);
4739     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4740
4741     /* initial status code */
4742     hr = IXMLHttpRequest_get_status(xhr, NULL);
4743     EXPECT_HR(hr, E_INVALIDARG);
4744
4745     status = 0xdeadbeef;
4746     hr = IXMLHttpRequest_get_status(xhr, &status);
4747     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4748     ok(status == 0xdeadbeef, "got %d\n", status);
4749
4750     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4751     ok(hr == E_FAIL, "got 0x%08x\n", hr);
4752
4753     /* invalid parameters */
4754     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4755     EXPECT_HR(hr, E_INVALIDARG);
4756
4757     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4758     EXPECT_HR(hr, E_INVALIDARG);
4759
4760     hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
4761     EXPECT_HR(hr, E_INVALIDARG);
4762
4763     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4764     EXPECT_HR(hr, E_INVALIDARG);
4765
4766     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4767     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4768
4769     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4770     EXPECT_HR(hr, E_INVALIDARG);
4771
4772     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4773     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4774
4775     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4776     EXPECT_HR(hr, E_INVALIDARG);
4777
4778     state = -1;
4779     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4780     EXPECT_HR(hr, S_OK);
4781     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4782
4783     event = create_dispevent();
4784
4785     EXPECT_REF(event, 1);
4786     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4787     EXPECT_HR(hr, S_OK);
4788     EXPECT_REF(event, 2);
4789
4790     g_unexpectedcall = g_expectedcall = 0;
4791
4792     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4793     EXPECT_HR(hr, S_OK);
4794
4795     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4796     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4797
4798     /* status code after ::open() */
4799     status = 0xdeadbeef;
4800     hr = IXMLHttpRequest_get_status(xhr, &status);
4801     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4802     ok(status == 0xdeadbeef, "got %d\n", status);
4803
4804     state = -1;
4805     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4806     EXPECT_HR(hr, S_OK);
4807     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4808
4809     hr = IXMLHttpRequest_abort(xhr);
4810     EXPECT_HR(hr, S_OK);
4811
4812     state = -1;
4813     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4814     EXPECT_HR(hr, S_OK);
4815     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4816         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4817
4818     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4819     EXPECT_HR(hr, S_OK);
4820
4821     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4822     EXPECT_HR(hr, S_OK);
4823
4824     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4825     EXPECT_HR(hr, E_INVALIDARG);
4826
4827     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4828     EXPECT_HR(hr, E_INVALIDARG);
4829
4830     V_VT(&varbody) = VT_BSTR;
4831     V_BSTR(&varbody) = _bstr_(bodyA);
4832
4833     hr = IXMLHttpRequest_send(xhr, varbody);
4834     if (hr == INET_E_RESOURCE_NOT_FOUND)
4835     {
4836         skip("No connection could be made with crossover.codeweavers.com\n");
4837         IXMLHttpRequest_Release(xhr);
4838         return;
4839     }
4840     EXPECT_HR(hr, S_OK);
4841
4842     /* response headers */
4843     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
4844     EXPECT_HR(hr, E_INVALIDARG);
4845     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
4846     EXPECT_HR(hr, S_OK);
4847     /* status line is stripped already */
4848     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
4849     ok(*str, "got empty headers\n");
4850     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
4851     EXPECT_HR(hr, S_OK);
4852     ok(str1 != str, "got %p\n", str1);
4853     SysFreeString(str1);
4854     SysFreeString(str);
4855
4856     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
4857     EXPECT_HR(hr, E_INVALIDARG);
4858     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
4859     EXPECT_HR(hr, E_INVALIDARG);
4860     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
4861     EXPECT_HR(hr, S_OK);
4862     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
4863     SysFreeString(str);
4864
4865     /* status code after ::send() */
4866     status = 0xdeadbeef;
4867     hr = IXMLHttpRequest_get_status(xhr, &status);
4868     EXPECT_HR(hr, S_OK);
4869     ok(status == 200, "got %d\n", status);
4870
4871     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
4872     EXPECT_HR(hr, E_INVALIDARG);
4873
4874     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4875     EXPECT_HR(hr, S_OK);
4876     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
4877     SysFreeString(str);
4878
4879     /* another ::send() after completed request */
4880     V_VT(&varbody) = VT_BSTR;
4881     V_BSTR(&varbody) = _bstr_(bodyA);
4882
4883     hr = IXMLHttpRequest_send(xhr, varbody);
4884     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4885
4886     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4887     EXPECT_HR(hr, S_OK);
4888     /* the server currently returns "FAILED" because the Content-Type header is
4889      * not what the server expects */
4890     if(hr == S_OK)
4891     {
4892         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4893             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4894         SysFreeString(bstrResponse);
4895     }
4896
4897     /* POST: VT_VARIANT|VT_BYREF body */
4898     V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
4899     V_VARIANTREF(&varbody_ref) = &varbody;
4900     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4901     EXPECT_HR(hr, S_OK);
4902     hr = IXMLHttpRequest_send(xhr, varbody_ref);
4903     EXPECT_HR(hr, S_OK);
4904
4905     /* GET request */
4906     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
4907     EXPECT_HR(hr, S_OK);
4908
4909     V_VT(&varbody) = VT_EMPTY;
4910
4911     hr = IXMLHttpRequest_send(xhr, varbody);
4912     if (hr == INET_E_RESOURCE_NOT_FOUND)
4913     {
4914         skip("No connection could be made with crossover.codeweavers.com\n");
4915         IXMLHttpRequest_Release(xhr);
4916         return;
4917     }
4918     EXPECT_HR(hr, S_OK);
4919
4920     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4921     EXPECT_HR(hr, E_INVALIDARG);
4922
4923     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4924     EXPECT_HR(hr, S_OK);
4925     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4926         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4927     SysFreeString(bstrResponse);
4928
4929     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4930     EXPECT_HR(hr, E_INVALIDARG);
4931
4932     V_VT(&varbody) = VT_EMPTY;
4933     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4934     EXPECT_HR(hr, S_OK);
4935     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4936     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4937
4938     bound = -1;
4939     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4940     EXPECT_HR(hr, S_OK);
4941     ok(bound == 0, "got %d, expected zero bound\n", bound);
4942
4943     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4944     EXPECT_HR(hr, S_OK);
4945     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4946     SafeArrayUnaccessData(V_ARRAY(&varbody));
4947
4948     VariantClear(&varbody);
4949
4950     /* get_responseStream */
4951     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
4952     EXPECT_HR(hr, E_INVALIDARG);
4953
4954     V_VT(&varbody) = VT_EMPTY;
4955     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4956     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
4957     EXPECT_HR(hr, S_OK);
4958     EXPECT_REF(V_UNKNOWN(&varbody), 1);
4959
4960     g = NULL;
4961     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
4962     EXPECT_HR(hr, S_OK);
4963     ok(g != NULL, "got %p\n", g);
4964
4965     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4966     EXPECT_HR(hr, S_OK);
4967     if(hr == S_OK)
4968     {
4969         test_IObjectSafety_common(safety);
4970         IObjectSafety_Release(safety);
4971     }
4972
4973     IDispatch_Release(event);
4974
4975     /* interaction with object site */
4976     EXPECT_REF(xhr, 1);
4977     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4978     EXPECT_HR(hr, S_OK);
4979 todo_wine {
4980     EXPECT_REF(xhr, 1);
4981     EXPECT_REF(obj_site, 1);
4982 }
4983
4984     IObjectWithSite_AddRef(obj_site);
4985 todo_wine {
4986     EXPECT_REF(obj_site, 2);
4987     EXPECT_REF(xhr, 1);
4988 }
4989     IObjectWithSite_Release(obj_site);
4990
4991     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
4992     EXPECT_HR(hr, S_OK);
4993 todo_wine {
4994     EXPECT_REF(xhr, 1);
4995     EXPECT_REF(obj_site, 1);
4996     EXPECT_REF(obj_site2, 1);
4997     ok(obj_site != obj_site2, "expected new instance\n");
4998 }
4999     SET_EXPECT(site_qi_IServiceProvider);
5000     SET_EXPECT(sp_queryservice_SID_SBindHost);
5001     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5002     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
5003     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
5004     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
5005
5006     /* calls to IHTMLDocument2 */
5007     SET_EXPECT(htmldoc2_get_all);
5008     SET_EXPECT(collection_get_length);
5009     SET_EXPECT(htmldoc2_get_url);
5010
5011     SET_EXPECT(site_qi_IXMLDOMDocument);
5012     SET_EXPECT(site_qi_IOleClientSite);
5013
5014     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
5015     EXPECT_HR(hr, S_OK);
5016
5017     CHECK_CALLED(site_qi_IServiceProvider);
5018 todo_wine
5019     CHECK_CALLED(sp_queryservice_SID_SBindHost);
5020     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5021 todo_wine {
5022     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
5023     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
5024     /* this one isn't very reliable
5025     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
5026
5027     CHECK_CALLED(htmldoc2_get_all);
5028     CHECK_CALLED(collection_get_length);
5029     CHECK_CALLED(htmldoc2_get_url);
5030
5031     CHECK_CALLED(site_qi_IXMLDOMDocument);
5032     CHECK_CALLED(site_qi_IOleClientSite);
5033 }
5034     IObjectWithSite_Release(obj_site);
5035
5036     /* try to set site another time */
5037
5038     /* to be removed once IObjectWithSite is properly separated */
5039     SET_EXPECT(site_qi_IServiceProvider);
5040     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5041
5042     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5043     EXPECT_HR(hr, S_OK);
5044
5045     todo_wine EXPECT_REF(xhr, 1);
5046     IXMLHttpRequest_Release(xhr);
5047
5048     /* still works after request is released */
5049
5050     /* to be removed once IObjectWithSite is properly separated */
5051     SET_EXPECT(site_qi_IServiceProvider);
5052     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5053
5054     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5055     EXPECT_HR(hr, S_OK);
5056     IObjectWithSite_Release(obj_site2);
5057
5058     free_bstrs();
5059 }
5060
5061 static void test_IXMLDOMDocument2(void)
5062 {
5063     static const WCHAR emptyW[] = {0};
5064     IXMLDOMDocument2 *doc2, *dtddoc2;
5065     IXMLDOMDocument *doc;
5066     IXMLDOMParseError* err;
5067     IDispatchEx *dispex;
5068     VARIANT_BOOL b;
5069     VARIANT var;
5070     HRESULT r;
5071     LONG res;
5072
5073     doc = create_document(&IID_IXMLDOMDocument);
5074     if (!doc) return;
5075
5076     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
5077     if (!dtddoc2)
5078     {
5079         IXMLDOMDocument_Release(doc);
5080         return;
5081     }
5082
5083     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
5084     ok( r == S_OK, "ret %08x\n", r );
5085     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
5086
5087     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
5088     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
5089     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5090
5091     err = NULL;
5092     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
5093     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5094     ok(err != NULL, "expected a pointer\n");
5095     if (err)
5096     {
5097         res = 0;
5098         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5099         /* XML_E_NOTWF */
5100         ok(res == E_XML_NOTWF, "got %08x\n", res);
5101         IXMLDOMParseError_Release(err);
5102     }
5103
5104     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
5105     ok( r == S_OK, "loadXML failed\n");
5106     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5107
5108     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
5109     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5110
5111     err = NULL;
5112     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5113     ok(err != NULL, "expected a pointer\n");
5114     if (err)
5115     {
5116         res = 0;
5117         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5118         /* XML_E_NODTD */
5119         ok(res == E_XML_NODTD, "got %08x\n", res);
5120         IXMLDOMParseError_Release(err);
5121     }
5122
5123     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5124     ok( r == S_OK, "ret %08x\n", r );
5125     if(r == S_OK)
5126     {
5127         IDispatchEx_Release(dispex);
5128     }
5129
5130     /* we will check if the variant got cleared */
5131     IXMLDOMDocument2_AddRef(doc2);
5132     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5133
5134     V_VT(&var) = VT_UNKNOWN;
5135     V_UNKNOWN(&var) = (IUnknown *)doc2;
5136
5137     /* invalid calls */
5138     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5139     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5140     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5141
5142     /* valid call */
5143     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5144     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5145     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5146     V_VT(&var) = VT_R4;
5147
5148     /* the variant didn't get cleared*/
5149     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5150
5151     /* setProperty tests */
5152     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5153     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5154     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5155     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5156     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5157     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5158
5159     V_VT(&var) = VT_BSTR;
5160     V_BSTR(&var) = SysAllocString(emptyW);
5161     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5162     ok(r == S_OK, "got 0x%08x\n", r);
5163     VariantClear(&var);
5164
5165     V_VT(&var) = VT_I2;
5166     V_I2(&var) = 0;
5167     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5168     ok(r == E_FAIL, "got 0x%08x\n", r);
5169
5170     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5171     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5172     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5173     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5174
5175     IXMLDOMDocument2_Release( doc2 );
5176     IXMLDOMDocument_Release( doc );
5177
5178     /* DTD validation */
5179     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5180     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5181     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5182     err = NULL;
5183     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5184     ok(err != NULL, "expected pointer\n");
5185     if (err)
5186     {
5187         res = 0;
5188         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5189         ok(res == 0, "got %08x\n", res);
5190         IXMLDOMParseError_Release(err);
5191     }
5192
5193     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5194     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5195     err = NULL;
5196     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5197     ok(err != NULL, "expected pointer\n");
5198     if (err)
5199     {
5200         res = 0;
5201         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5202         /* XML_ELEMENT_UNDECLARED */
5203         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5204         IXMLDOMParseError_Release(err);
5205     }
5206
5207     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5208     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5209     err = NULL;
5210     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5211     ok(err != NULL, "expected pointer\n");
5212     if (err)
5213     {
5214         res = 0;
5215         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5216         /* XML_ELEMENT_ID_NOT_FOUND */
5217         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5218         IXMLDOMParseError_Release(err);
5219     }
5220
5221     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5222     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5223     err = NULL;
5224     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5225     ok(err != NULL, "expected pointer\n");
5226     if (err)
5227     {
5228         res = 0;
5229         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5230         /* XML_EMPTY_NOT_ALLOWED */
5231         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5232         IXMLDOMParseError_Release(err);
5233     }
5234
5235     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5236     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5237     err = NULL;
5238     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5239     ok(err != NULL, "expected pointer\n");
5240     if (err)
5241     {
5242         res = 0;
5243         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5244         /* XML_ROOT_NAME_MISMATCH */
5245         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5246         IXMLDOMParseError_Release(err);
5247     }
5248
5249     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5250     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5251     err = NULL;
5252     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5253     ok(err != NULL, "expected pointer\n");
5254     if (err)
5255     {
5256         res = 0;
5257         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5258         /* XML_INVALID_CONTENT */
5259         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5260         IXMLDOMParseError_Release(err);
5261     }
5262
5263     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5264     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5265     err = NULL;
5266     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5267     ok(err != NULL, "expected pointer\n");
5268     if (err)
5269     {
5270         res = 0;
5271         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5272         /* XML_ATTRIBUTE_NOT_DEFINED */
5273         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5274         IXMLDOMParseError_Release(err);
5275     }
5276
5277     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5278     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5279     err = NULL;
5280     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5281     ok(err != NULL, "expected pointer\n");
5282     if (err)
5283     {
5284         res = 0;
5285         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5286         /* XML_ATTRIBUTE_FIXED */
5287         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5288         IXMLDOMParseError_Release(err);
5289     }
5290
5291     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5292     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5293     err = NULL;
5294     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5295     ok(err != NULL, "expected pointer\n");
5296     if (err)
5297     {
5298         res = 0;
5299         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5300         /* XML_ATTRIBUTE_VALUE */
5301         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5302         IXMLDOMParseError_Release(err);
5303     }
5304
5305     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5306     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5307     err = NULL;
5308     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5309     ok(err != NULL, "expected pointer\n");
5310     if (err)
5311     {
5312         res = 0;
5313         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5314         /* XML_ILLEGAL_TEXT */
5315         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5316         IXMLDOMParseError_Release(err);
5317     }
5318
5319     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5320     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5321     err = NULL;
5322     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5323     ok(err != NULL, "expected pointer\n");
5324     if (err)
5325     {
5326         res = 0;
5327         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5328         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5329         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5330         IXMLDOMParseError_Release(err);
5331     }
5332
5333     IXMLDOMDocument2_Release( dtddoc2 );
5334     free_bstrs();
5335 }
5336
5337 #define helper_ole_check(expr) { \
5338     HRESULT r = expr; \
5339     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5340 }
5341
5342 #define helper_expect_list_and_release(list, expstr) { \
5343     char *str = list_to_string(list); \
5344     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5345     if (list) IXMLDOMNodeList_Release(list); \
5346 }
5347
5348 #define helper_expect_bstr_and_release(bstr, str) { \
5349     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5350        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5351     SysFreeString(bstr); \
5352 }
5353
5354 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5355 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5356 {
5357     IXMLDOMNode *node1, *node2;
5358     IXMLDOMNodeList *list;
5359     BSTR bstr;
5360
5361     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5362     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5363     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5364     helper_ole_check(IXMLDOMNodeList_reset(list));
5365     helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
5366
5367     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5368     helper_expect_list_and_release(list, "T1.E1.E5.E1.E2.D1 E2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 T4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1");
5369     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5370     if (str)
5371     {
5372         helper_expect_bstr_and_release(bstr, str);
5373     }
5374     else
5375     {
5376         helper_expect_bstr_and_release(bstr, "This is a description.");
5377     }
5378     IXMLDOMNode_Release(node1);
5379
5380     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5381     helper_expect_list_and_release(list, "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
5382     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5383     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5384     IXMLDOMNode_Release(node2);
5385 }
5386
5387 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5388 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5389 {
5390     IXMLDOMNode *node1, *node2;
5391     IXMLDOMNodeList *list;
5392     BSTR bstr;
5393
5394     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5395     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5396     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5397     helper_ole_check(IXMLDOMNodeList_reset(list));
5398     helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
5399
5400     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5401     helper_expect_list_and_release(list, "T1.E2.E10.E2.E2.D1 E2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 T7.E2.E10.E2.E2.D1");
5402     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5403     if (str)
5404     {
5405         helper_expect_bstr_and_release(bstr, str);
5406     }
5407     else
5408     {
5409         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5410     }
5411     IXMLDOMNode_Release(node1);
5412
5413     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5414     helper_expect_list_and_release(list, "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
5415     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5416     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5417     IXMLDOMNode_Release(node2);
5418 }
5419
5420 static void test_whitespace(void)
5421 {
5422     VARIANT_BOOL b;
5423     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5424
5425     doc1 = create_document(&IID_IXMLDOMDocument2);
5426     doc2 = create_document(&IID_IXMLDOMDocument2);
5427     if (!doc1 || !doc2) return;
5428
5429     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5430     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5431     ok(b == VARIANT_FALSE, "expected false\n");
5432     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5433     ok(b == VARIANT_TRUE, "expected true\n");
5434
5435     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5436     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5437     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5438     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5439
5440     /* switch to XPath */
5441     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5442     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5443
5444     check_ws_ignored(doc1, NULL);
5445     check_ws_preserved(doc2, NULL);
5446
5447     /* new instances copy the property */
5448     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5449     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5450
5451     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5452     ok(b == VARIANT_FALSE, "expected false\n");
5453     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5454     ok(b == VARIANT_TRUE, "expected true\n");
5455
5456     check_ws_ignored(doc3, NULL);
5457     check_ws_preserved(doc4, NULL);
5458
5459     /* setting after loading xml affects trimming of leading/trailing ws only */
5460     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5461     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5462
5463     /* the trailing "\n            " isn't there, because it was ws-only node */
5464     check_ws_ignored(doc1, "\n                This is a description. ");
5465     check_ws_preserved(doc2, "This is a description.");
5466
5467     /* it takes effect on reload */
5468     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5469     ok(b == VARIANT_TRUE, "expected true\n");
5470     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5471     ok(b == VARIANT_FALSE, "expected false\n");
5472
5473     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5474     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5475     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5476     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5477
5478     check_ws_preserved(doc1, NULL);
5479     check_ws_ignored(doc2, NULL);
5480
5481     /* other instances follow suit */
5482     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5483     ok(b == VARIANT_TRUE, "expected true\n");
5484     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5485     ok(b == VARIANT_FALSE, "expected false\n");
5486
5487     check_ws_preserved(doc3, NULL);
5488     check_ws_ignored(doc4, NULL);
5489
5490     IXMLDOMDocument_Release(doc1);
5491     IXMLDOMDocument_Release(doc2);
5492     IXMLDOMDocument_Release(doc3);
5493     IXMLDOMDocument_Release(doc4);
5494     free_bstrs();
5495 }
5496
5497 typedef struct {
5498     const GUID *clsid;
5499     const char *name;
5500     const char *ns;
5501     HRESULT hr;
5502 } selection_ns_t;
5503
5504 /* supposed to be tested with szExampleXML */
5505 static const selection_ns_t selection_ns_data[] = {
5506     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5507     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5508     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5509
5510     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5511     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5512     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5513
5514     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5515     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5516     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5517
5518     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5519     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5520     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5521
5522     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5523     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5524     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5525
5526     { NULL }
5527 };
5528
5529 static void test_XPath(void)
5530 {
5531     const selection_ns_t *ptr = selection_ns_data;
5532     VARIANT var;
5533     VARIANT_BOOL b;
5534     IXMLDOMDocument2 *doc;
5535     IXMLDOMDocument *doc2;
5536     IXMLDOMNode *rootNode;
5537     IXMLDOMNode *elem1Node;
5538     IXMLDOMNode *node;
5539     IXMLDOMNodeList *list;
5540     IXMLDOMElement *elem;
5541     IXMLDOMAttribute *attr;
5542     DOMNodeType type;
5543     HRESULT hr;
5544     LONG len;
5545     BSTR str;
5546
5547     doc = create_document(&IID_IXMLDOMDocument2);
5548     if (!doc) return;
5549
5550     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5551     EXPECT_HR(hr, S_OK);
5552     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5553
5554     /* switch to XPath */
5555     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5556
5557     /* some simple queries*/
5558     EXPECT_REF(doc, 1);
5559     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5560     EXPECT_HR(hr, S_OK);
5561     EXPECT_REF(doc, 1);
5562     EXPECT_LIST_LEN(list, 1);
5563
5564     EXPECT_REF(list, 1);
5565     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5566     EXPECT_HR(hr, S_OK);
5567     EXPECT_REF(list, 1);
5568     EXPECT_REF(rootNode, 1);
5569
5570     hr = IXMLDOMNodeList_reset(list);
5571     EXPECT_HR(hr, S_OK);
5572     expect_list_and_release(list, "E2.D1");
5573
5574 if (0)
5575 {
5576     /* namespace:: axis test is disabled until namespace definitions
5577        are supported as attribute nodes, currently it's another node type */
5578     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5579     EXPECT_HR(hr, S_OK);
5580     len = -1;
5581     hr = IXMLDOMNodeList_get_length(list, &len);
5582     EXPECT_HR(hr, S_OK);
5583     ok(len == 2, "got %d\n", len);
5584
5585     hr = IXMLDOMNodeList_nextNode(list, &node);
5586     EXPECT_HR(hr, S_OK);
5587     type = NODE_INVALID;
5588     hr = IXMLDOMNode_get_nodeType(node, &type);
5589     EXPECT_HR(hr, S_OK);
5590     ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5591     IXMLDOMNode_Release(node);
5592
5593     IXMLDOMNodeList_Release(list);
5594 }
5595
5596     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5597     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5598
5599     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5600     expect_list_and_release(list, "E3.E2.E2.D1");
5601
5602     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5603     /* using get_item for query results advances the position */
5604     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5605     expect_node(node, "E2.E2.D1");
5606     IXMLDOMNode_Release(node);
5607     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5608     expect_node(node, "E4.E2.D1");
5609     IXMLDOMNode_Release(node);
5610     ole_check(IXMLDOMNodeList_reset(list));
5611     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5612
5613     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5614     expect_list_and_release(list, "E2.D1");
5615
5616     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5617     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5618     ole_check(IXMLDOMNodeList_reset(list));
5619     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5620
5621     /* select an attribute */
5622     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5623     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5624
5625     /* would evaluate to a number */
5626     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5627     /* would evaluate to a boolean */
5628     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5629     /* would evaluate to a string */
5630     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5631
5632     /* no results */
5633     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5634     expect_list_and_release(list, "");
5635     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5636     expect_list_and_release(list, "");
5637     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5638     expect_list_and_release(list, "");
5639     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5640     expect_list_and_release(list, "");
5641
5642     /* foo undeclared in document node */
5643     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5644     /* undeclared in <root> node */
5645     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5646     /* undeclared in <elem> node */
5647     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5648     /* but this trick can be used */
5649     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5650     expect_list_and_release(list, "E3.E4.E2.D1");
5651
5652     /* it has to be declared in SelectionNamespaces */
5653     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5654         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5655
5656     /* now the namespace can be used */
5657     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5658     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5659     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5660     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5661     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5662     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5663     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5664     expect_list_and_release(list, "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
5665
5666     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5667     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5668         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5669
5670     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5671
5672     VariantInit(&var);
5673     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5674     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5675     if (V_VT(&var) == VT_BSTR)
5676         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5677
5678     /* extra attributes - same thing*/
5679     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5680         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5681     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5682
5683     IXMLDOMNode_Release(rootNode);
5684     IXMLDOMNode_Release(elem1Node);
5685
5686     /* alter document with already built list */
5687     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5688     EXPECT_HR(hr, S_OK);
5689     EXPECT_LIST_LEN(list, 1);
5690
5691     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5692     EXPECT_HR(hr, S_OK);
5693     EXPECT_REF(rootNode, 1);
5694     EXPECT_REF(doc, 1);
5695
5696     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5697     EXPECT_HR(hr, S_OK);
5698     IXMLDOMNode_Release(rootNode);
5699
5700     EXPECT_LIST_LEN(list, 1);
5701
5702     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5703     EXPECT_HR(hr, S_OK);
5704     EXPECT_REF(rootNode, 1);
5705
5706     IXMLDOMNodeList_Release(list);
5707
5708     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5709     EXPECT_HR(hr, S_OK);
5710     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5711     SysFreeString(str);
5712     IXMLDOMNode_Release(rootNode);
5713
5714     /* alter node from list and get it another time */
5715     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5716     EXPECT_HR(hr, S_OK);
5717     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5718
5719     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5720     EXPECT_HR(hr, S_OK);
5721     EXPECT_LIST_LEN(list, 1);
5722
5723     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5724     EXPECT_HR(hr, S_OK);
5725
5726     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5727     EXPECT_HR(hr, S_OK);
5728
5729     V_VT(&var) = VT_I2;
5730     V_I2(&var) = 1;
5731     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5732     EXPECT_HR(hr, S_OK);
5733     IXMLDOMElement_Release(elem);
5734     IXMLDOMNode_Release(rootNode);
5735
5736     /* now check attribute to be present */
5737     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5738     EXPECT_HR(hr, S_OK);
5739
5740     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5741     EXPECT_HR(hr, S_OK);
5742
5743     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5744     EXPECT_HR(hr, S_OK);
5745     IXMLDOMAttribute_Release(attr);
5746
5747     IXMLDOMElement_Release(elem);
5748     IXMLDOMNode_Release(rootNode);
5749
5750     /* and now check for attribute in original document */
5751     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5752     EXPECT_HR(hr, S_OK);
5753
5754     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5755     EXPECT_HR(hr, S_OK);
5756     IXMLDOMAttribute_Release(attr);
5757
5758     IXMLDOMElement_Release(elem);
5759
5760     /* attach node from list to another document */
5761     doc2 = create_document(&IID_IXMLDOMDocument);
5762
5763     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5764     EXPECT_HR(hr, S_OK);
5765     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5766
5767     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5768     EXPECT_HR(hr, S_OK);
5769     EXPECT_LIST_LEN(list, 1);
5770
5771     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5772     EXPECT_HR(hr, S_OK);
5773     EXPECT_REF(rootNode, 1);
5774
5775     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5776     EXPECT_HR(hr, S_OK);
5777     EXPECT_REF(rootNode, 1);
5778     EXPECT_REF(doc2, 1);
5779     EXPECT_REF(list, 1);
5780
5781     EXPECT_LIST_LEN(list, 1);
5782
5783     IXMLDOMNode_Release(rootNode);
5784     IXMLDOMNodeList_Release(list);
5785     IXMLDOMDocument_Release(doc2);
5786     IXMLDOMDocument2_Release(doc);
5787
5788     while (ptr->clsid)
5789     {
5790         hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5791         if (hr != S_OK)
5792         {
5793             win_skip("can't create instance of %s\n", ptr->name);
5794             ptr++;
5795             continue;
5796         }
5797
5798         hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5799         EXPECT_HR(hr, S_OK);
5800         ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5801
5802         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5803         EXPECT_HR(hr, S_OK);
5804
5805         V_VT(&var) = VT_BSTR;
5806         V_BSTR(&var) = _bstr_(ptr->ns);
5807
5808         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5809         ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5810
5811         V_VT(&var) = VT_EMPTY;
5812         hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5813         EXPECT_HR(hr, S_OK);
5814         ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5815         ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5816         VariantClear(&var);
5817
5818         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5819         EXPECT_HR(hr, S_OK);
5820         if (hr == S_OK)
5821             expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5822
5823         IXMLDOMDocument2_Release(doc);
5824         ptr++;
5825     }
5826
5827     free_bstrs();
5828 }
5829
5830 static void test_cloneNode(void )
5831 {
5832     IXMLDOMDocument *doc, *doc2;
5833     VARIANT_BOOL b;
5834     IXMLDOMNodeList *pList;
5835     IXMLDOMNamedNodeMap *mapAttr;
5836     LONG length, length1;
5837     LONG attr_cnt, attr_cnt1;
5838     IXMLDOMNode *node;
5839     IXMLDOMNode *node_clone;
5840     IXMLDOMNode *node_first;
5841     HRESULT hr;
5842
5843     doc = create_document(&IID_IXMLDOMDocument);
5844     if (!doc) return;
5845
5846     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5847     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5848
5849     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5850     ok( hr == S_OK, "ret %08x\n", hr );
5851     ok( node != NULL, "node %p\n", node );
5852
5853     /* Check invalid parameter */
5854     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5855     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5856
5857     /* All Children */
5858     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5859     ok( hr == S_OK, "ret %08x\n", hr );
5860     ok( node_clone != NULL, "node %p\n", node );
5861
5862     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5863     ok( hr == S_OK, "ret %08x\n", hr );
5864     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5865     ok( hr == S_OK, "ret %08x\n", hr );
5866     IXMLDOMDocument_Release(doc2);
5867     IXMLDOMNode_Release(node_first);
5868
5869     hr = IXMLDOMNode_get_childNodes(node, &pList);
5870     ok( hr == S_OK, "ret %08x\n", hr );
5871     length = 0;
5872     hr = IXMLDOMNodeList_get_length(pList, &length);
5873     ok( hr == S_OK, "ret %08x\n", hr );
5874     ok(length == 1, "got %d\n", length);
5875     IXMLDOMNodeList_Release(pList);
5876
5877     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5878     ok( hr == S_OK, "ret %08x\n", hr );
5879     attr_cnt = 0;
5880     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5881     ok( hr == S_OK, "ret %08x\n", hr );
5882     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5883     IXMLDOMNamedNodeMap_Release(mapAttr);
5884
5885     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5886     ok( hr == S_OK, "ret %08x\n", hr );
5887     length1 = 0;
5888     hr = IXMLDOMNodeList_get_length(pList, &length1);
5889     ok(length1 == 1, "got %d\n", length1);
5890     ok( hr == S_OK, "ret %08x\n", hr );
5891     IXMLDOMNodeList_Release(pList);
5892
5893     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5894     ok( hr == S_OK, "ret %08x\n", hr );
5895     attr_cnt1 = 0;
5896     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5897     ok( hr == S_OK, "ret %08x\n", hr );
5898     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5899     IXMLDOMNamedNodeMap_Release(mapAttr);
5900
5901     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5902     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5903     IXMLDOMNode_Release(node_clone);
5904
5905     /* No Children */
5906     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5907     ok( hr == S_OK, "ret %08x\n", hr );
5908     ok( node_clone != NULL, "node %p\n", node );
5909
5910     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5911     ok(hr == S_FALSE, "ret %08x\n", hr );
5912
5913     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5914     ok(hr == S_OK, "ret %08x\n", hr );
5915     hr = IXMLDOMNodeList_get_length(pList, &length1);
5916     ok(hr == S_OK, "ret %08x\n", hr );
5917     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5918     IXMLDOMNodeList_Release(pList);
5919
5920     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5921     ok(hr == S_OK, "ret %08x\n", hr );
5922     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5923     ok(hr == S_OK, "ret %08x\n", hr );
5924     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5925     IXMLDOMNamedNodeMap_Release(mapAttr);
5926
5927     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5928     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5929     IXMLDOMNode_Release(node_clone);
5930
5931     IXMLDOMNode_Release(node);
5932     IXMLDOMDocument_Release(doc);
5933     free_bstrs();
5934 }
5935
5936 static void test_xmlTypes(void)
5937 {
5938     IXMLDOMDocument *doc;
5939     IXMLDOMElement *pRoot;
5940     HRESULT hr;
5941     IXMLDOMComment *pComment;
5942     IXMLDOMElement *pElement;
5943     IXMLDOMAttribute *pAttribute;
5944     IXMLDOMNamedNodeMap *pAttribs;
5945     IXMLDOMCDATASection *pCDataSec;
5946     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5947     IXMLDOMDocumentFragment *pDocFrag = NULL;
5948     IXMLDOMEntityReference *pEntityRef = NULL;
5949     BSTR str;
5950     IXMLDOMNode *pNextChild;
5951     VARIANT v;
5952     LONG len = 0;
5953
5954     doc = create_document(&IID_IXMLDOMDocument);
5955     if (!doc) return;
5956
5957     pNextChild = (void*)0xdeadbeef;
5958     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5959     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5960
5961     pNextChild = (void*)0xdeadbeef;
5962     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5963     ok(hr == S_FALSE, "ret %08x\n", hr );
5964     ok(pNextChild == NULL, "pDocChild not NULL\n");
5965
5966     /* test previous Sibling */
5967     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5968     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5969
5970     pNextChild = (void*)0xdeadbeef;
5971     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5972     ok(hr == S_FALSE, "ret %08x\n", hr );
5973     ok(pNextChild == NULL, "pNextChild not NULL\n");
5974
5975     /* test get_dataType */
5976     V_VT(&v) = VT_EMPTY;
5977     hr = IXMLDOMDocument_get_dataType(doc, &v);
5978     ok(hr == S_FALSE, "ret %08x\n", hr );
5979     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5980     VariantClear(&v);
5981
5982     /* test implementation */
5983     hr = IXMLDOMDocument_get_implementation(doc, NULL);
5984     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5985
5986     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5987     ok(hr == S_OK, "ret %08x\n", hr );
5988     if(hr == S_OK)
5989     {
5990         VARIANT_BOOL hasFeature = VARIANT_TRUE;
5991         BSTR sEmpty = SysAllocStringLen(NULL, 0);
5992
5993         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5994         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5995
5996         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5997         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5998
5999         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6000         ok(hr == S_OK, "ret %08x\n", hr );
6001         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6002
6003         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
6004         ok(hr == S_OK, "ret %08x\n", hr );
6005         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
6006
6007         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
6008         ok(hr == S_OK, "ret %08x\n", hr );
6009         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
6010
6011         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6012         ok(hr == S_OK, "ret %08x\n", hr );
6013         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6014
6015         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
6016         ok(hr == S_OK, "ret %08x\n", hr );
6017         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6018
6019         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
6020         ok(hr == S_OK, "ret %08x\n", hr );
6021         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6022
6023         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
6024         ok(hr == S_OK, "ret %08x\n", hr );
6025         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6026
6027         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
6028         ok(hr == S_OK, "ret %08x\n", hr );
6029         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6030
6031         SysFreeString(sEmpty);
6032         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
6033     }
6034
6035     pRoot = (IXMLDOMElement*)0x1;
6036     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
6037     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6038     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6039
6040     pRoot = (IXMLDOMElement*)0x1;
6041     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
6042     ok(hr == E_FAIL, "ret %08x\n", hr );
6043     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6044
6045     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6046     ok(hr == S_OK, "ret %08x\n", hr );
6047     if(hr == S_OK)
6048     {
6049         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6050         ok(hr == S_OK, "ret %08x\n", hr );
6051         if(hr == S_OK)
6052         {
6053             /* Comment */
6054             str = SysAllocString(szComment);
6055             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
6056             SysFreeString(str);
6057             ok(hr == S_OK, "ret %08x\n", hr );
6058             if(hr == S_OK)
6059             {
6060                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
6061                 ok(hr == S_OK, "ret %08x\n", hr );
6062
6063                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
6064                 ok(hr == S_OK, "ret %08x\n", hr );
6065                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
6066                 SysFreeString(str);
6067
6068                 hr = IXMLDOMComment_get_xml(pComment, &str);
6069                 ok(hr == S_OK, "ret %08x\n", hr );
6070                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
6071                 SysFreeString(str);
6072
6073                 /* put data Tests */
6074                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
6075                 ok(hr == S_OK, "ret %08x\n", hr );
6076
6077                 /* get data Tests */
6078                 hr = IXMLDOMComment_get_data(pComment, &str);
6079                 ok(hr == S_OK, "ret %08x\n", hr );
6080                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
6081                 SysFreeString(str);
6082
6083                 /* Confirm XML text is good */
6084                 hr = IXMLDOMComment_get_xml(pComment, &str);
6085                 ok(hr == S_OK, "ret %08x\n", hr );
6086                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
6087                 SysFreeString(str);
6088
6089                 /* Confirm we get the put_data Text back */
6090                 hr = IXMLDOMComment_get_text(pComment, &str);
6091                 ok(hr == S_OK, "ret %08x\n", hr );
6092                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
6093                 SysFreeString(str);
6094
6095                 /* test length property */
6096                 hr = IXMLDOMComment_get_length(pComment, &len);
6097                 ok(hr == S_OK, "ret %08x\n", hr );
6098                 ok(len == 21, "expected 21 got %d\n", len);
6099
6100                 /* test substringData */
6101                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
6102                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6103
6104                 /* test substringData - Invalid offset */
6105                 str = (BSTR)&szElement;
6106                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
6107                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6108                 ok( str == NULL, "incorrect string\n");
6109
6110                 /* test substringData - Invalid offset */
6111                 str = (BSTR)&szElement;
6112                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
6113                 ok(hr == S_FALSE, "ret %08x\n", hr );
6114                 ok( str == NULL, "incorrect string\n");
6115
6116                 /* test substringData - Invalid size */
6117                 str = (BSTR)&szElement;
6118                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
6119                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6120                 ok( str == NULL, "incorrect string\n");
6121
6122                 /* test substringData - Invalid size */
6123                 str = (BSTR)&szElement;
6124                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
6125                 ok(hr == S_FALSE, "ret %08x\n", hr );
6126                 ok( str == NULL, "incorrect string\n");
6127
6128                 /* test substringData - Start of string */
6129                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
6130                 ok(hr == S_OK, "ret %08x\n", hr );
6131                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6132                 SysFreeString(str);
6133
6134                 /* test substringData - Middle of string */
6135                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
6136                 ok(hr == S_OK, "ret %08x\n", hr );
6137                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6138                 SysFreeString(str);
6139
6140                 /* test substringData - End of string */
6141                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
6142                 ok(hr == S_OK, "ret %08x\n", hr );
6143                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6144                 SysFreeString(str);
6145
6146                 /* test appendData */
6147                 hr = IXMLDOMComment_appendData(pComment, NULL);
6148                 ok(hr == S_OK, "ret %08x\n", hr );
6149
6150                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
6151                 ok(hr == S_OK, "ret %08x\n", hr );
6152
6153                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
6154                 ok(hr == S_OK, "ret %08x\n", hr );
6155
6156                 hr = IXMLDOMComment_get_text(pComment, &str);
6157                 ok(hr == S_OK, "ret %08x\n", hr );
6158                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6159                 SysFreeString(str);
6160
6161                 /* test insertData */
6162                 str = SysAllocStringLen(NULL, 0);
6163                 hr = IXMLDOMComment_insertData(pComment, -1, str);
6164                 ok(hr == S_OK, "ret %08x\n", hr );
6165
6166                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
6167                 ok(hr == S_OK, "ret %08x\n", hr );
6168
6169                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
6170                 ok(hr == S_OK, "ret %08x\n", hr );
6171
6172                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
6173                 ok(hr == S_OK, "ret %08x\n", hr );
6174
6175                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
6176                 ok(hr == S_OK, "ret %08x\n", hr );
6177
6178                 hr = IXMLDOMComment_insertData(pComment, 0, str);
6179                 ok(hr == S_OK, "ret %08x\n", hr );
6180                 SysFreeString(str);
6181
6182                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
6183                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6184
6185                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
6186                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6187
6188                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
6189                 ok(hr == S_OK, "ret %08x\n", hr );
6190
6191                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
6192                 ok(hr == S_OK, "ret %08x\n", hr );
6193
6194                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
6195                 ok(hr == S_OK, "ret %08x\n", hr );
6196
6197                 hr = IXMLDOMComment_get_text(pComment, &str);
6198                 ok(hr == S_OK, "ret %08x\n", hr );
6199                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6200                 SysFreeString(str);
6201
6202                 /* delete data */
6203                 /* invalid arguments */
6204                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6205                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6206
6207                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6208                 ok(hr == S_OK, "ret %08x\n", hr );
6209
6210                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6211                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6212
6213                 hr = IXMLDOMComment_get_length(pComment, &len);
6214                 ok(hr == S_OK, "ret %08x\n", hr );
6215                 ok(len == 43, "expected 43 got %d\n", len);
6216
6217                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6218                 ok(hr == S_OK, "ret %08x\n", hr );
6219
6220                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6221                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6222
6223                 /* delete from start */
6224                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6225                 ok(hr == S_OK, "ret %08x\n", hr );
6226
6227                 hr = IXMLDOMComment_get_length(pComment, &len);
6228                 ok(hr == S_OK, "ret %08x\n", hr );
6229                 ok(len == 38, "expected 38 got %d\n", len);
6230
6231                 hr = IXMLDOMComment_get_text(pComment, &str);
6232                 ok(hr == S_OK, "ret %08x\n", hr );
6233                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6234                 SysFreeString(str);
6235
6236                 /* delete from end */
6237                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6238                 ok(hr == S_OK, "ret %08x\n", hr );
6239
6240                 hr = IXMLDOMComment_get_length(pComment, &len);
6241                 ok(hr == S_OK, "ret %08x\n", hr );
6242                 ok(len == 35, "expected 35 got %d\n", len);
6243
6244                 hr = IXMLDOMComment_get_text(pComment, &str);
6245                 ok(hr == S_OK, "ret %08x\n", hr );
6246                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6247                 SysFreeString(str);
6248
6249                 /* delete from inside */
6250                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6251                 ok(hr == S_OK, "ret %08x\n", hr );
6252
6253                 hr = IXMLDOMComment_get_length(pComment, &len);
6254                 ok(hr == S_OK, "ret %08x\n", hr );
6255                 ok(len == 2, "expected 2 got %d\n", len);
6256
6257                 hr = IXMLDOMComment_get_text(pComment, &str);
6258                 ok(hr == S_OK, "ret %08x\n", hr );
6259                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6260                 SysFreeString(str);
6261
6262                 /* delete whole data ... */
6263                 hr = IXMLDOMComment_get_length(pComment, &len);
6264                 ok(hr == S_OK, "ret %08x\n", hr );
6265
6266                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6267                 ok(hr == S_OK, "ret %08x\n", hr );
6268                 /* ... and try again with empty string */
6269                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6270                 ok(hr == S_OK, "ret %08x\n", hr );
6271
6272                 /* ::replaceData() */
6273                 V_VT(&v) = VT_BSTR;
6274                 V_BSTR(&v) = SysAllocString(szstr1);
6275                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6276                 ok(hr == S_OK, "ret %08x\n", hr );
6277                 VariantClear(&v);
6278
6279                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6280                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6281                 hr = IXMLDOMComment_get_text(pComment, &str);
6282                 ok(hr == S_OK, "ret %08x\n", hr );
6283                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6284                 SysFreeString(str);
6285
6286                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6287                 ok(hr == S_OK, "ret %08x\n", hr );
6288                 hr = IXMLDOMComment_get_text(pComment, &str);
6289                 ok(hr == S_OK, "ret %08x\n", hr );
6290                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6291                 SysFreeString(str);
6292
6293                 /* NULL pointer means delete */
6294                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6295                 ok(hr == S_OK, "ret %08x\n", hr );
6296                 hr = IXMLDOMComment_get_text(pComment, &str);
6297                 ok(hr == S_OK, "ret %08x\n", hr );
6298                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6299                 SysFreeString(str);
6300
6301                 /* empty string means delete */
6302                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6303                 ok(hr == S_OK, "ret %08x\n", hr );
6304                 hr = IXMLDOMComment_get_text(pComment, &str);
6305                 ok(hr == S_OK, "ret %08x\n", hr );
6306                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6307                 SysFreeString(str);
6308
6309                 /* zero count means insert */
6310                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6311                 ok(hr == S_OK, "ret %08x\n", hr );
6312                 hr = IXMLDOMComment_get_text(pComment, &str);
6313                 ok(hr == S_OK, "ret %08x\n", hr );
6314                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6315                 SysFreeString(str);
6316
6317                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6318                 ok(hr == S_OK, "ret %08x\n", hr );
6319
6320                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6321                 ok(hr == S_OK, "ret %08x\n", hr );
6322                 hr = IXMLDOMComment_get_text(pComment, &str);
6323                 ok(hr == S_OK, "ret %08x\n", hr );
6324                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6325                 SysFreeString(str);
6326
6327                 /* nonempty string, count greater than its length */
6328                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6329                 ok(hr == S_OK, "ret %08x\n", hr );
6330                 hr = IXMLDOMComment_get_text(pComment, &str);
6331                 ok(hr == S_OK, "ret %08x\n", hr );
6332                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6333                 SysFreeString(str);
6334
6335                 /* nonempty string, count less than its length */
6336                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6337                 ok(hr == S_OK, "ret %08x\n", hr );
6338                 hr = IXMLDOMComment_get_text(pComment, &str);
6339                 ok(hr == S_OK, "ret %08x\n", hr );
6340                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6341                 SysFreeString(str);
6342
6343                 IXMLDOMComment_Release(pComment);
6344             }
6345
6346             /* Element */
6347             str = SysAllocString(szElement);
6348             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6349             SysFreeString(str);
6350             ok(hr == S_OK, "ret %08x\n", hr );
6351             if(hr == S_OK)
6352             {
6353                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6354                 ok(hr == S_OK, "ret %08x\n", hr );
6355
6356                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6357                 ok(hr == S_OK, "ret %08x\n", hr );
6358                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6359                 SysFreeString(str);
6360
6361                 hr = IXMLDOMElement_get_xml(pElement, &str);
6362                 ok(hr == S_OK, "ret %08x\n", hr );
6363                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6364                 SysFreeString(str);
6365
6366                 /* Attribute */
6367                 pAttribute = (IXMLDOMAttribute*)0x1;
6368                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6369                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6370                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6371
6372                 pAttribute = (IXMLDOMAttribute*)0x1;
6373                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6374                 ok(hr == E_FAIL, "ret %08x\n", hr );
6375                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6376
6377                 str = SysAllocString(szAttribute);
6378                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6379                 SysFreeString(str);
6380                 ok(hr == S_OK, "ret %08x\n", hr );
6381                 if(hr == S_OK)
6382                 {
6383                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6384
6385                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6386                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6387
6388                     pNextChild = (IXMLDOMNode *)0x1;
6389                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6390                     ok(hr == S_FALSE, "ret %08x\n", hr );
6391                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6392
6393                     /* test Previous Sibling*/
6394                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6395                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6396
6397                     pNextChild = (IXMLDOMNode *)0x1;
6398                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6399                     ok(hr == S_FALSE, "ret %08x\n", hr );
6400                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6401
6402                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6403                     ok(hr == E_FAIL, "ret %08x\n", hr );
6404                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6405
6406                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6407                     ok(hr == S_OK, "ret %08x\n", hr );
6408                     if ( hr == S_OK )
6409                     {
6410                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6411                         ok(hr == S_OK, "ret %08x\n", hr );
6412
6413                         IXMLDOMNamedNodeMap_Release(pAttribs);
6414                     }
6415
6416                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6417                     ok(hr == S_OK, "ret %08x\n", hr );
6418                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6419                     SysFreeString(str);
6420
6421                     /* test nodeName */
6422                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6423                     ok(hr == S_OK, "ret %08x\n", hr );
6424                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6425                     SysFreeString(str);
6426
6427                     /* test name property */
6428                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6429                     ok(hr == S_OK, "ret %08x\n", hr );
6430                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6431                     SysFreeString(str);
6432
6433                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6434                     ok(hr == S_OK, "ret %08x\n", hr );
6435                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6436                     SysFreeString(str);
6437
6438                     IXMLDOMAttribute_Release(pAttribute);
6439
6440                     /* Check Element again with the Add Attribute*/
6441                     hr = IXMLDOMElement_get_xml(pElement, &str);
6442                     ok(hr == S_OK, "ret %08x\n", hr );
6443                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6444                     SysFreeString(str);
6445                 }
6446
6447                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6448                 ok(hr == S_OK, "ret %08x\n", hr );
6449
6450                 hr = IXMLDOMElement_get_xml(pElement, &str);
6451                 ok(hr == S_OK, "ret %08x\n", hr );
6452                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6453                 SysFreeString(str);
6454
6455                 /* Test for reversible escaping */
6456                 str = SysAllocString( szStrangeChars );
6457                 hr = IXMLDOMElement_put_text(pElement, str);
6458                 ok(hr == S_OK, "ret %08x\n", hr );
6459                 SysFreeString( str );
6460
6461                 hr = IXMLDOMElement_get_xml(pElement, &str);
6462                 ok(hr == S_OK, "ret %08x\n", hr );
6463                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6464                 SysFreeString(str);
6465
6466                 hr = IXMLDOMElement_get_text(pElement, &str);
6467                 ok(hr == S_OK, "ret %08x\n", hr );
6468                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6469                 SysFreeString(str);
6470
6471                 IXMLDOMElement_Release(pElement);
6472             }
6473
6474             /* CData Section */
6475             str = SysAllocString(szCData);
6476             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6477             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6478
6479             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6480             SysFreeString(str);
6481             ok(hr == S_OK, "ret %08x\n", hr );
6482             if(hr == S_OK)
6483             {
6484                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6485                 VARIANT var;
6486
6487                 VariantInit(&var);
6488
6489                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6490                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6491
6492                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6493                 ok(hr == S_OK, "ret %08x\n", hr );
6494
6495                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6496                 ok(hr == S_OK, "ret %08x\n", hr );
6497                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6498                 SysFreeString(str);
6499
6500                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6501                 ok(hr == S_OK, "ret %08x\n", hr );
6502                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6503                 SysFreeString(str);
6504
6505                 /* test lastChild */
6506                 pNextChild = (IXMLDOMNode*)0x1;
6507                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6508                 ok(hr == S_FALSE, "ret %08x\n", hr );
6509                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6510
6511                 /* put data Tests */
6512                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6513                 ok(hr == S_OK, "ret %08x\n", hr );
6514
6515                 /* Confirm XML text is good */
6516                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6517                 ok(hr == S_OK, "ret %08x\n", hr );
6518                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6519                 SysFreeString(str);
6520
6521                 /* Confirm we get the put_data Text back */
6522                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6523                 ok(hr == S_OK, "ret %08x\n", hr );
6524                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6525                 SysFreeString(str);
6526
6527                 /* test length property */
6528                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6529                 ok(hr == S_OK, "ret %08x\n", hr );
6530                 ok(len == 21, "expected 21 got %d\n", len);
6531
6532                 /* test get data */
6533                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6534                 ok(hr == S_OK, "ret %08x\n", hr );
6535                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6536                 SysFreeString(str);
6537
6538                 /* test substringData */
6539                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6540                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6541
6542                 /* test substringData - Invalid offset */
6543                 str = (BSTR)&szElement;
6544                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6545                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6546                 ok( str == NULL, "incorrect string\n");
6547
6548                 /* test substringData - Invalid offset */
6549                 str = (BSTR)&szElement;
6550                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6551                 ok(hr == S_FALSE, "ret %08x\n", hr );
6552                 ok( str == NULL, "incorrect string\n");
6553
6554                 /* test substringData - Invalid size */
6555                 str = (BSTR)&szElement;
6556                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6557                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6558                 ok( str == NULL, "incorrect string\n");
6559
6560                 /* test substringData - Invalid size */
6561                 str = (BSTR)&szElement;
6562                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6563                 ok(hr == S_FALSE, "ret %08x\n", hr );
6564                 ok( str == NULL, "incorrect string\n");
6565
6566                 /* test substringData - Start of string */
6567                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6568                 ok(hr == S_OK, "ret %08x\n", hr );
6569                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6570                 SysFreeString(str);
6571
6572                 /* test substringData - Middle of string */
6573                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6574                 ok(hr == S_OK, "ret %08x\n", hr );
6575                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6576                 SysFreeString(str);
6577
6578                 /* test substringData - End of string */
6579                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6580                 ok(hr == S_OK, "ret %08x\n", hr );
6581                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6582                 SysFreeString(str);
6583
6584                 /* test appendData */
6585                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6586                 ok(hr == S_OK, "ret %08x\n", hr );
6587
6588                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6589                 ok(hr == S_OK, "ret %08x\n", hr );
6590
6591                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6592                 ok(hr == S_OK, "ret %08x\n", hr );
6593
6594                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6595                 ok(hr == S_OK, "ret %08x\n", hr );
6596                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6597                 SysFreeString(str);
6598
6599                 /* test insertData */
6600                 str = SysAllocStringLen(NULL, 0);
6601                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6602                 ok(hr == S_OK, "ret %08x\n", hr );
6603
6604                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6605                 ok(hr == S_OK, "ret %08x\n", hr );
6606
6607                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6608                 ok(hr == S_OK, "ret %08x\n", hr );
6609
6610                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6611                 ok(hr == S_OK, "ret %08x\n", hr );
6612
6613                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6614                 ok(hr == S_OK, "ret %08x\n", hr );
6615
6616                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6617                 ok(hr == S_OK, "ret %08x\n", hr );
6618                 SysFreeString(str);
6619
6620                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6621                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6622
6623                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6624                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6625
6626                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6627                 ok(hr == S_OK, "ret %08x\n", hr );
6628
6629                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6630                 ok(hr == S_OK, "ret %08x\n", hr );
6631
6632                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6633                 ok(hr == S_OK, "ret %08x\n", hr );
6634
6635                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6636                 ok(hr == S_OK, "ret %08x\n", hr );
6637                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6638                 SysFreeString(str);
6639
6640                 /* delete data */
6641                 /* invalid arguments */
6642                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6643                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6644
6645                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6646                 ok(hr == S_OK, "ret %08x\n", hr );
6647
6648                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6649                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6650
6651                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6652                 ok(hr == S_OK, "ret %08x\n", hr );
6653                 ok(len == 43, "expected 43 got %d\n", len);
6654
6655                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6656                 ok(hr == S_OK, "ret %08x\n", hr );
6657
6658                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6659                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6660
6661                 /* delete from start */
6662                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6663                 ok(hr == S_OK, "ret %08x\n", hr );
6664
6665                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6666                 ok(hr == S_OK, "ret %08x\n", hr );
6667                 ok(len == 38, "expected 38 got %d\n", len);
6668
6669                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6670                 ok(hr == S_OK, "ret %08x\n", hr );
6671                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6672                 SysFreeString(str);
6673
6674                 /* delete from end */
6675                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6676                 ok(hr == S_OK, "ret %08x\n", hr );
6677
6678                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6679                 ok(hr == S_OK, "ret %08x\n", hr );
6680                 ok(len == 35, "expected 35 got %d\n", len);
6681
6682                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6683                 ok(hr == S_OK, "ret %08x\n", hr );
6684                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6685                 SysFreeString(str);
6686
6687                 /* delete from inside */
6688                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6689                 ok(hr == S_OK, "ret %08x\n", hr );
6690
6691                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6692                 ok(hr == S_OK, "ret %08x\n", hr );
6693                 ok(len == 2, "expected 2 got %d\n", len);
6694
6695                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6696                 ok(hr == S_OK, "ret %08x\n", hr );
6697                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6698                 SysFreeString(str);
6699
6700                 /* delete whole data ... */
6701                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6702                 ok(hr == S_OK, "ret %08x\n", hr );
6703
6704                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6705                 ok(hr == S_OK, "ret %08x\n", hr );
6706
6707                 /* ... and try again with empty string */
6708                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6709                 ok(hr == S_OK, "ret %08x\n", hr );
6710
6711                 /* ::replaceData() */
6712                 V_VT(&v) = VT_BSTR;
6713                 V_BSTR(&v) = SysAllocString(szstr1);
6714                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6715                 ok(hr == S_OK, "ret %08x\n", hr );
6716                 VariantClear(&v);
6717
6718                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6719                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6720                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6721                 ok(hr == S_OK, "ret %08x\n", hr );
6722                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6723                 SysFreeString(str);
6724
6725                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6726                 ok(hr == S_OK, "ret %08x\n", hr );
6727                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6728                 ok(hr == S_OK, "ret %08x\n", hr );
6729                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6730                 SysFreeString(str);
6731
6732                 /* NULL pointer means delete */
6733                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6734                 ok(hr == S_OK, "ret %08x\n", hr );
6735                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6736                 ok(hr == S_OK, "ret %08x\n", hr );
6737                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6738                 SysFreeString(str);
6739
6740                 /* empty string means delete */
6741                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6742                 ok(hr == S_OK, "ret %08x\n", hr );
6743                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6744                 ok(hr == S_OK, "ret %08x\n", hr );
6745                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6746                 SysFreeString(str);
6747
6748                 /* zero count means insert */
6749                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6750                 ok(hr == S_OK, "ret %08x\n", hr );
6751                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6752                 ok(hr == S_OK, "ret %08x\n", hr );
6753                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6754                 SysFreeString(str);
6755
6756                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6757                 ok(hr == S_OK, "ret %08x\n", hr );
6758
6759                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6760                 ok(hr == S_OK, "ret %08x\n", hr );
6761                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6762                 ok(hr == S_OK, "ret %08x\n", hr );
6763                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6764                 SysFreeString(str);
6765
6766                 /* nonempty string, count greater than its length */
6767                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6768                 ok(hr == S_OK, "ret %08x\n", hr );
6769                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6770                 ok(hr == S_OK, "ret %08x\n", hr );
6771                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6772                 SysFreeString(str);
6773
6774                 /* nonempty string, count less than its length */
6775                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6776                 ok(hr == S_OK, "ret %08x\n", hr );
6777                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6778                 ok(hr == S_OK, "ret %08x\n", hr );
6779                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6780                 SysFreeString(str);
6781
6782                 IXMLDOMCDATASection_Release(pCDataSec);
6783             }
6784
6785             /* Document Fragments */
6786             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6787             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6788
6789             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6790             ok(hr == S_OK, "ret %08x\n", hr );
6791             if(hr == S_OK)
6792             {
6793                 IXMLDOMNode *node;
6794
6795                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6796                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6797
6798                 node = (IXMLDOMNode *)0x1;
6799                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6800                 ok(hr == S_FALSE, "ret %08x\n", hr );
6801                 ok(node == NULL, "expected NULL, got %p\n", node);
6802
6803                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6804                 ok(hr == S_OK, "ret %08x\n", hr );
6805
6806                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6807                 ok(hr == S_OK, "ret %08x\n", hr );
6808                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6809                 SysFreeString(str);
6810
6811                 /* test next Sibling*/
6812                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6813                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6814
6815                 node = (IXMLDOMNode *)0x1;
6816                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6817                 ok(hr == S_FALSE, "ret %08x\n", hr );
6818                 ok(node == NULL, "next sibling not NULL\n");
6819
6820                 /* test Previous Sibling*/
6821                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6822                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6823
6824                 node = (IXMLDOMNode *)0x1;
6825                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6826                 ok(hr == S_FALSE, "ret %08x\n", hr );
6827                 ok(node == NULL, "previous sibling not NULL\n");
6828
6829                 IXMLDOMDocumentFragment_Release(pDocFrag);
6830             }
6831
6832             /* Entity References */
6833             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6834             ok(hr == E_FAIL, "ret %08x\n", hr );
6835             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6836             ok(hr == E_FAIL, "ret %08x\n", hr );
6837
6838             str = SysAllocString(szEntityRef);
6839             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6840             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6841
6842             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6843             SysFreeString(str);
6844             ok(hr == S_OK, "ret %08x\n", hr );
6845             if(hr == S_OK)
6846             {
6847                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6848                 ok(hr == S_OK, "ret %08x\n", hr );
6849
6850                 /* test get_xml*/
6851                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6852                 ok(hr == S_OK, "ret %08x\n", hr );
6853                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6854                 SysFreeString(str);
6855
6856                 IXMLDOMEntityReference_Release(pEntityRef);
6857             }
6858
6859             IXMLDOMElement_Release( pRoot );
6860         }
6861     }
6862
6863     IXMLDOMDocument_Release(doc);
6864
6865     free_bstrs();
6866 }
6867
6868 typedef struct {
6869     const char *name;
6870     const char *type;
6871     HRESULT hr;
6872 } put_datatype_t;
6873
6874 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6875    So many of the names have been changed to reflect this. */
6876 static put_datatype_t put_datatype_data[] = {
6877     { "test_inval",      "abcdefg",     E_FAIL },
6878     { "test_bool",       "Boolean",     S_OK },
6879     { "test_string",     "String",      S_OK },
6880     { "test_number",     "number",      S_OK },
6881     { "test_int",        "InT",         S_OK },
6882     { "test_fixed",      "fixed.14.4",  S_OK },
6883     { "test_datetime",   "DateTime",    S_OK },
6884     { "test_datetimetz", "DateTime.tz", S_OK },
6885     { "test_date",       "Date",        S_OK },
6886     { "test_time",       "Time",        S_OK },
6887     { "test_timetz",     "Time.tz",     S_OK },
6888     { "test_I1",         "I1",          S_OK },
6889     { "test_I2",         "I2",          S_OK },
6890     { "test_I4",         "I4",          S_OK },
6891     { "test_UI1",        "UI1",         S_OK },
6892     { "test_UI2",        "UI2",         S_OK },
6893     { "test_UI4",        "UI4",         S_OK },
6894     { "test_r4",         "r4",          S_OK },
6895     { "test_r8",         "r8",          S_OK },
6896     { "test_float",      "float",       S_OK },
6897     { "test_uuid",       "UuId",        S_OK },
6898     { "test_binhex",     "bin.hex",     S_OK },
6899     { "test_binbase64",  "bin.base64",  S_OK },
6900     { NULL }
6901 };
6902
6903 typedef struct {
6904     DOMNodeType type;
6905     HRESULT hr;
6906 } put_datatype_notype_t;
6907
6908 static put_datatype_notype_t put_dt_notype[] = {
6909     { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6910     { NODE_DOCUMENT_FRAGMENT,      E_FAIL },
6911     { NODE_ENTITY_REFERENCE,       E_FAIL },
6912     { NODE_CDATA_SECTION,          E_FAIL },
6913     { NODE_COMMENT,                E_FAIL },
6914     { NODE_INVALID }
6915 };
6916
6917 static void test_put_dataType( void )
6918 {
6919     const put_datatype_notype_t *ptr2 = put_dt_notype;
6920     const put_datatype_t *ptr = put_datatype_data;
6921     IXMLDOMElement *root, *element;
6922     BSTR nameW, type1W, type2W;
6923     IXMLDOMDocument *doc;
6924     HRESULT hr;
6925
6926     doc = create_document(&IID_IXMLDOMDocument);
6927     if (!doc) return;
6928
6929     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6930     EXPECT_HR(hr, E_INVALIDARG);
6931
6932     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6933     EXPECT_HR(hr, S_OK);
6934
6935     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6936     EXPECT_HR(hr, S_OK);
6937
6938     hr = IXMLDOMElement_put_dataType(root, NULL);
6939     EXPECT_HR(hr, E_INVALIDARG);
6940
6941     while (ptr->name)
6942     {
6943         hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6944         EXPECT_HR(hr, S_OK);
6945         if(hr == S_OK)
6946         {
6947             hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6948             EXPECT_HR(hr, S_OK);
6949
6950             hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6951             ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6952
6953             IXMLDOMElement_Release(element);
6954         }
6955         ptr++;
6956     }
6957
6958     /* check changing types */
6959     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6960     EXPECT_HR(hr, S_OK);
6961
6962     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6963     EXPECT_HR(hr, S_OK);
6964
6965     hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6966     EXPECT_HR(hr, S_OK);
6967
6968     hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6969     EXPECT_HR(hr, S_OK);
6970
6971     IXMLDOMElement_Release(element);
6972
6973     /* try to set type for node without a type */
6974     nameW  = _bstr_("testname");
6975     type1W = _bstr_("string");
6976     type2W = _bstr_("number");
6977     while (ptr2->type != NODE_INVALID)
6978     {
6979         IXMLDOMNode *node;
6980         VARIANT type;
6981
6982         V_VT(&type) = VT_I2;
6983         V_I2(&type) = ptr2->type;
6984
6985         hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
6986         EXPECT_HR(hr, S_OK);
6987         if(hr == S_OK)
6988         {
6989             hr = IXMLDOMElement_appendChild(root, node, NULL);
6990             EXPECT_HR(hr, S_OK);
6991
6992             hr = IXMLDOMNode_put_dataType(node, NULL);
6993             EXPECT_HR(hr, E_INVALIDARG);
6994
6995             hr = IXMLDOMNode_put_dataType(node, type1W);
6996             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6997             hr = IXMLDOMNode_put_dataType(node, type2W);
6998             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6999
7000             IXMLDOMNode_Release(node);
7001         }
7002         ptr2++;
7003     }
7004
7005     IXMLDOMElement_Release(root);
7006     IXMLDOMDocument_Release(doc);
7007     free_bstrs();
7008 }
7009
7010 static void test_save(void)
7011 {
7012     IXMLDOMDocument *doc, *doc2;
7013     IXMLDOMElement *root;
7014     VARIANT file, vDoc;
7015     BSTR sOrig, sNew, filename;
7016     char buffer[100];
7017     DWORD read = 0;
7018     HANDLE hfile;
7019     HRESULT hr;
7020
7021     doc = create_document(&IID_IXMLDOMDocument);
7022     if (!doc) return;
7023
7024     doc2 = create_document(&IID_IXMLDOMDocument);
7025     if (!doc2)
7026     {
7027         IXMLDOMDocument_Release(doc);
7028         return;
7029     }
7030
7031     /* save to IXMLDOMDocument */
7032     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7033     EXPECT_HR(hr, S_OK);
7034
7035     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7036     EXPECT_HR(hr, S_OK);
7037
7038     V_VT(&vDoc) = VT_UNKNOWN;
7039     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
7040
7041     hr = IXMLDOMDocument_save(doc, vDoc);
7042     EXPECT_HR(hr, S_OK);
7043
7044     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7045     EXPECT_HR(hr, S_OK);
7046
7047     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7048     EXPECT_HR(hr, S_OK);
7049
7050     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7051
7052     SysFreeString(sOrig);
7053     SysFreeString(sNew);
7054
7055     IXMLDOMElement_Release(root);
7056     IXMLDOMDocument_Release(doc2);
7057
7058     /* save to path */
7059     V_VT(&file) = VT_BSTR;
7060     V_BSTR(&file) = _bstr_("test.xml");
7061
7062     hr = IXMLDOMDocument_save(doc, file);
7063     EXPECT_HR(hr, S_OK);
7064
7065     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7066     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7067     if(hfile == INVALID_HANDLE_VALUE) return;
7068
7069     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7070     ok(read != 0, "could not read file\n");
7071     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7072
7073     CloseHandle(hfile);
7074     DeleteFile("test.xml");
7075
7076     /* save to path VT_BSTR | VT_BYREF */
7077     filename = _bstr_("test.xml");
7078     V_VT(&file) = VT_BSTR | VT_BYREF;
7079     V_BSTRREF(&file) = &filename;
7080
7081     hr = IXMLDOMDocument_save(doc, file);
7082     EXPECT_HR(hr, S_OK);
7083
7084     IXMLDOMDocument_Release(doc);
7085
7086     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7087     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7088     if(hfile == INVALID_HANDLE_VALUE) return;
7089
7090     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7091     ok(read != 0, "could not read file\n");
7092     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7093
7094     CloseHandle(hfile);
7095     DeleteFile("test.xml");
7096     free_bstrs();
7097 }
7098
7099 static void test_testTransforms(void)
7100 {
7101     IXMLDOMDocument *doc, *docSS;
7102     IXMLDOMNode *pNode;
7103     VARIANT_BOOL bSucc;
7104
7105     HRESULT hr;
7106
7107     doc = create_document(&IID_IXMLDOMDocument);
7108     if (!doc) return;
7109
7110     docSS = create_document(&IID_IXMLDOMDocument);
7111     if (!docSS)
7112     {
7113         IXMLDOMDocument_Release(doc);
7114         return;
7115     }
7116
7117     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7118     ok(hr == S_OK, "ret %08x\n", hr );
7119
7120     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7121     ok(hr == S_OK, "ret %08x\n", hr );
7122
7123     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7124     ok(hr == S_OK, "ret %08x\n", hr );
7125     if(hr == S_OK)
7126     {
7127         BSTR bOut;
7128
7129         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7130         ok(hr == S_OK, "ret %08x\n", hr );
7131         if(hr == S_OK)
7132         {
7133             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7134             SysFreeString(bOut);
7135         }
7136
7137         IXMLDOMNode_Release(pNode);
7138     }
7139
7140     IXMLDOMDocument_Release(docSS);
7141     IXMLDOMDocument_Release(doc);
7142
7143     free_bstrs();
7144 }
7145
7146 static void test_namespaces(void)
7147 {
7148     static const CHAR namespaces_xmlA[] =
7149         "<?xml version=\"1.0\"?>\n"
7150         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7151         "  <XMI.content>"
7152         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7153         "  </XMI.content>"
7154         "</XMI>";
7155
7156     IXMLDOMDocument *doc;
7157     IXMLDOMElement *elem;
7158     IXMLDOMNode *node;
7159
7160     VARIANT_BOOL b;
7161     VARIANT var;
7162     HRESULT hr;
7163     BSTR str;
7164
7165     doc = create_document(&IID_IXMLDOMDocument);
7166     if (!doc) return;
7167
7168     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7169     EXPECT_HR(hr, S_OK);
7170     ok(b == VARIANT_TRUE, "got %d\n", b);
7171
7172     str = (BSTR)0xdeadbeef;
7173     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7174     EXPECT_HR(hr, S_FALSE);
7175     ok(str == NULL, "got %p\n", str);
7176
7177     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7178     EXPECT_HR(hr, S_OK);
7179     if(hr == S_OK)
7180     {
7181         IXMLDOMAttribute *attr;
7182         IXMLDOMNode *node2;
7183
7184         hr = IXMLDOMNode_get_firstChild(node, &node2);
7185         EXPECT_HR(hr, S_OK);
7186         ok(node2 != NULL, "got %p\n", node2);
7187
7188         /* Test get_prefix */
7189         hr = IXMLDOMNode_get_prefix(node2, NULL);
7190         EXPECT_HR(hr, E_INVALIDARG);
7191         /* NOTE: Need to test that arg2 gets cleared on Error. */
7192
7193         hr = IXMLDOMNode_get_prefix(node2, &str);
7194         EXPECT_HR(hr, S_OK);
7195         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7196         SysFreeString(str);
7197
7198         hr = IXMLDOMNode_get_nodeName(node2, &str);
7199         EXPECT_HR(hr, S_OK);
7200         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7201         SysFreeString(str);
7202
7203         /* Test get_namespaceURI */
7204         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7205         EXPECT_HR(hr, E_INVALIDARG);
7206         /* NOTE: Need to test that arg2 gets cleared on Error. */
7207
7208         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7209         EXPECT_HR(hr, S_OK);
7210         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7211         SysFreeString(str);
7212
7213         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7214         EXPECT_HR(hr, S_OK);
7215
7216         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7217         EXPECT_HR(hr, S_OK);
7218
7219         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7220         EXPECT_HR(hr, S_OK);
7221         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7222         SysFreeString(str);
7223
7224         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7225         EXPECT_HR(hr, S_OK);
7226         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7227         SysFreeString(str);
7228
7229         IXMLDOMAttribute_Release(attr);
7230         IXMLDOMElement_Release(elem);
7231
7232         IXMLDOMNode_Release(node2);
7233         IXMLDOMNode_Release(node);
7234     }
7235
7236     IXMLDOMDocument_Release(doc);
7237
7238     /* create on element and try to alter namespace after that */
7239     doc = create_document(&IID_IXMLDOMDocument);
7240     if (!doc) return;
7241
7242     V_VT(&var) = VT_I2;
7243     V_I2(&var) = NODE_ELEMENT;
7244
7245     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7246     EXPECT_HR(hr, S_OK);
7247
7248     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7249     EXPECT_HR(hr, S_OK);
7250
7251     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7252     EXPECT_HR(hr, S_OK);
7253
7254     V_VT(&var) = VT_BSTR;
7255     V_BSTR(&var) = _bstr_("ns/uri2");
7256
7257     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7258     EXPECT_HR(hr, E_INVALIDARG);
7259
7260     V_VT(&var) = VT_BSTR;
7261     V_BSTR(&var) = _bstr_("ns/uri");
7262
7263     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7264     EXPECT_HR(hr, S_OK);
7265
7266     hr = IXMLDOMElement_get_xml(elem, &str);
7267     EXPECT_HR(hr, S_OK);
7268     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7269     SysFreeString(str);
7270
7271     IXMLDOMElement_Release(elem);
7272     IXMLDOMDocument_Release(doc);
7273
7274     /* create on element and try to alter namespace after that */
7275     doc = create_document_version(60, &IID_IXMLDOMDocument);
7276     if (!doc) return;
7277
7278     V_VT(&var) = VT_I2;
7279     V_I2(&var) = NODE_ELEMENT;
7280
7281     hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7282     EXPECT_HR(hr, S_OK);
7283
7284     hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7285     EXPECT_HR(hr, S_OK);
7286
7287     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7288     EXPECT_HR(hr, S_OK);
7289
7290     /* try same prefix, different uri */
7291     V_VT(&var) = VT_BSTR;
7292     V_BSTR(&var) = _bstr_("ns/uri2");
7293
7294     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7295     EXPECT_HR(hr, E_INVALIDARG);
7296
7297     /* try same prefix and uri */
7298     V_VT(&var) = VT_BSTR;
7299     V_BSTR(&var) = _bstr_("ns/uri");
7300
7301     hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7302     EXPECT_HR(hr, S_OK);
7303
7304     hr = IXMLDOMElement_get_xml(elem, &str);
7305     EXPECT_HR(hr, S_OK);
7306     ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s\n", wine_dbgstr_w(str));
7307     SysFreeString(str);
7308
7309     IXMLDOMElement_Release(elem);
7310     IXMLDOMDocument_Release(doc);
7311
7312     free_bstrs();
7313 }
7314
7315 static void test_FormattingXML(void)
7316 {
7317     IXMLDOMDocument *doc;
7318     IXMLDOMElement *pElement;
7319     VARIANT_BOOL bSucc;
7320     HRESULT hr;
7321     BSTR str;
7322     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7323     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7324
7325     doc = create_document(&IID_IXMLDOMDocument);
7326     if (!doc) return;
7327
7328     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7329     ok(hr == S_OK, "ret %08x\n", hr );
7330     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7331
7332     if(bSucc == VARIANT_TRUE)
7333     {
7334         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7335         ok(hr == S_OK, "ret %08x\n", hr );
7336         if(hr == S_OK)
7337         {
7338             hr = IXMLDOMElement_get_xml(pElement, &str);
7339             ok(hr == S_OK, "ret %08x\n", hr );
7340             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7341             SysFreeString(str);
7342
7343             IXMLDOMElement_Release(pElement);
7344         }
7345     }
7346
7347     IXMLDOMDocument_Release(doc);
7348
7349     free_bstrs();
7350 }
7351
7352 typedef struct _nodetypedvalue_t {
7353     const char *name;
7354     VARTYPE type;
7355     const char *value; /* value in string format */
7356 } nodetypedvalue_t;
7357
7358 static const nodetypedvalue_t get_nodetypedvalue[] = {
7359     { "root/string",    VT_BSTR, "Wine" },
7360     { "root/string2",   VT_BSTR, "String" },
7361     { "root/number",    VT_BSTR, "12.44" },
7362     { "root/number2",   VT_BSTR, "-3.71e3" },
7363     { "root/int",       VT_I4,   "-13" },
7364     { "root/fixed",     VT_CY,   "7322.9371" },
7365     { "root/bool",      VT_BOOL, "-1" },
7366     { "root/datetime",  VT_DATE, "40135.14" },
7367     { "root/datetimetz",VT_DATE, "37813.59" },
7368     { "root/date",      VT_DATE, "665413" },
7369     { "root/time",      VT_DATE, "0.5813889" },
7370     { "root/timetz",    VT_DATE, "1.112512" },
7371     { "root/i1",        VT_I1,   "-13" },
7372     { "root/i2",        VT_I2,   "31915" },
7373     { "root/i4",        VT_I4,   "-312232" },
7374     { "root/ui1",       VT_UI1,  "123" },
7375     { "root/ui2",       VT_UI2,  "48282" },
7376     { "root/ui4",       VT_UI4,  "949281" },
7377     { "root/r4",        VT_R4,   "213124" },
7378     { "root/r8",        VT_R8,   "0.412" },
7379     { "root/float",     VT_R8,   "41221.421" },
7380     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7381     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7382     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7383     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7384     { 0 }
7385 };
7386
7387 static void test_nodeTypedValue(void)
7388 {
7389     const nodetypedvalue_t *entry = get_nodetypedvalue;
7390     IXMLDOMDocumentType *doctype, *doctype2;
7391     IXMLDOMProcessingInstruction *pi;
7392     IXMLDOMDocumentFragment *frag;
7393     IXMLDOMDocument *doc, *doc2;
7394     IXMLDOMCDATASection *cdata;
7395     IXMLDOMComment *comment;
7396     IXMLDOMNode *node;
7397     VARIANT_BOOL b;
7398     VARIANT value;
7399     HRESULT hr;
7400
7401     doc = create_document(&IID_IXMLDOMDocument);
7402     if (!doc) return;
7403
7404     b = VARIANT_FALSE;
7405     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7406     ok(hr == S_OK, "ret %08x\n", hr );
7407     ok(b == VARIANT_TRUE, "got %d\n", b);
7408
7409     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7410     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7411
7412     V_VT(&value) = VT_BSTR;
7413     V_BSTR(&value) = NULL;
7414     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7415     ok(hr == S_FALSE, "ret %08x\n", hr );
7416     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7417
7418     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7419     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7420
7421     V_VT(&value) = VT_EMPTY;
7422     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7423     ok(hr == S_FALSE, "ret %08x\n", hr );
7424     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7425
7426     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7427     ok(hr == S_OK, "ret %08x\n", hr );
7428
7429     V_VT(&value) = VT_BSTR;
7430     V_BSTR(&value) = NULL;
7431     hr = IXMLDOMNode_get_nodeValue(node, &value);
7432     ok(hr == S_FALSE, "ret %08x\n", hr );
7433     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7434
7435     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7436     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7437
7438     IXMLDOMNode_Release(node);
7439
7440     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7441     ok(hr == S_OK, "ret %08x\n", hr );
7442     {
7443         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7444
7445         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7446         ok(hr == S_OK, "ret %08x\n", hr );
7447         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7448         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7449         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7450             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7451         VariantClear(&value);
7452         IXMLDOMNode_Release(node);
7453     }
7454
7455     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7456     ok(hr == S_OK, "ret %08x\n", hr );
7457     {
7458         V_VT(&value) = VT_NULL;
7459         V_BSTR(&value) = (void*)0xdeadbeef;
7460         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7461         ok(hr == S_OK, "ret %08x\n", hr );
7462         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7463         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7464         IXMLDOMProcessingInstruction_Release(pi);
7465         VariantClear(&value);
7466     }
7467
7468     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7469     ok(hr == S_OK, "ret %08x\n", hr );
7470     {
7471         V_VT(&value) = VT_NULL;
7472         V_BSTR(&value) = (void*)0xdeadbeef;
7473         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7474         ok(hr == S_OK, "ret %08x\n", hr );
7475         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7476         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7477         IXMLDOMCDATASection_Release(cdata);
7478         VariantClear(&value);
7479     }
7480
7481     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7482     ok(hr == S_OK, "ret %08x\n", hr );
7483     {
7484         V_VT(&value) = VT_NULL;
7485         V_BSTR(&value) = (void*)0xdeadbeef;
7486         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7487         ok(hr == S_OK, "ret %08x\n", hr );
7488         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7489         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7490         IXMLDOMComment_Release(comment);
7491         VariantClear(&value);
7492     }
7493
7494     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7495     ok(hr == S_OK, "ret %08x\n", hr );
7496     {
7497         V_VT(&value) = VT_EMPTY;
7498         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7499         ok(hr == S_FALSE, "ret %08x\n", hr );
7500         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7501         IXMLDOMDocumentFragment_Release(frag);
7502     }
7503
7504     doc2 = create_document(&IID_IXMLDOMDocument);
7505
7506     b = VARIANT_FALSE;
7507     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7508     ok(hr == S_OK, "ret %08x\n", hr );
7509     ok(b == VARIANT_TRUE, "got %d\n", b);
7510
7511     EXPECT_REF(doc2, 1);
7512
7513     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7514     ok(hr == S_OK, "ret %08x\n", hr );
7515
7516     EXPECT_REF(doc2, 1);
7517     todo_wine EXPECT_REF(doctype, 2);
7518
7519     {
7520         V_VT(&value) = VT_EMPTY;
7521         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7522         ok(hr == S_FALSE, "ret %08x\n", hr );
7523         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7524     }
7525
7526     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7527     ok(hr == S_OK, "ret %08x\n", hr );
7528     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7529
7530     IXMLDOMDocumentType_Release(doctype2);
7531     IXMLDOMDocumentType_Release(doctype);
7532
7533     IXMLDOMDocument_Release(doc2);
7534
7535     while (entry->name)
7536     {
7537         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7538         ok(hr == S_OK, "ret %08x\n", hr );
7539
7540         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7541         ok(hr == S_OK, "ret %08x\n", hr );
7542         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7543
7544         if (entry->type == (VT_ARRAY|VT_UI1))
7545         {
7546             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7547                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7548         }
7549
7550         if (entry->type != VT_BSTR)
7551         {
7552            if (entry->type == VT_DATE ||
7553                entry->type == VT_R8 ||
7554                entry->type == VT_CY)
7555            {
7556                if (entry->type == VT_DATE)
7557                {
7558                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7559                    ok(hr == S_OK, "ret %08x\n", hr );
7560                }
7561                hr = VariantChangeTypeEx(&value, &value,
7562                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7563                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7564                ok(hr == S_OK, "ret %08x\n", hr );
7565            }
7566            else
7567            {
7568                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7569                ok(hr == S_OK, "ret %08x\n", hr );
7570            }
7571
7572            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7573            if (entry->type == (VT_ARRAY|VT_UI1))
7574            {
7575                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7576                   "expected %s\n", entry->value);
7577            }
7578            else
7579                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7580                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7581         }
7582         else
7583            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7584                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7585
7586         VariantClear( &value );
7587         IXMLDOMNode_Release(node);
7588
7589         entry++;
7590     }
7591
7592     IXMLDOMDocument_Release(doc);
7593     free_bstrs();
7594 }
7595
7596 static void test_TransformWithLoadingLocalFile(void)
7597 {
7598     IXMLDOMDocument *doc;
7599     IXMLDOMDocument *xsl;
7600     IXMLDOMNode *pNode;
7601     VARIANT_BOOL bSucc;
7602     HRESULT hr;
7603     HANDLE file;
7604     DWORD dwWritten;
7605     char lpPathBuffer[MAX_PATH];
7606     int i;
7607
7608     /* Create a Temp File. */
7609     GetTempPathA(MAX_PATH, lpPathBuffer);
7610     strcat(lpPathBuffer, "customers.xml" );
7611
7612     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7613     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7614     if(file == INVALID_HANDLE_VALUE)
7615         return;
7616
7617     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7618     CloseHandle(file);
7619
7620     /* Correct path to not include a escape character. */
7621     for(i=0; i < strlen(lpPathBuffer); i++)
7622     {
7623         if(lpPathBuffer[i] == '\\')
7624             lpPathBuffer[i] = '/';
7625     }
7626
7627     doc = create_document(&IID_IXMLDOMDocument);
7628     if (!doc) return;
7629
7630     xsl = create_document(&IID_IXMLDOMDocument);
7631     if (!xsl)
7632     {
7633         IXMLDOMDocument2_Release(doc);
7634         return;
7635     }
7636
7637     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7638     ok(hr == S_OK, "ret %08x\n", hr );
7639     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7640     if(bSucc == VARIANT_TRUE)
7641     {
7642         BSTR sXSL;
7643         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7644         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7645         BSTR sFileName = _bstr_(lpPathBuffer);
7646         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7647
7648         sXSL = SysAllocStringLen(NULL, nLegnth);
7649         lstrcpyW(sXSL, sPart1);
7650         lstrcatW(sXSL, sFileName);
7651         lstrcatW(sXSL, sPart2);
7652
7653         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7654         ok(hr == S_OK, "ret %08x\n", hr );
7655         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7656         if(bSucc == VARIANT_TRUE)
7657         {
7658             BSTR sResult;
7659
7660             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7661             ok(hr == S_OK, "ret %08x\n", hr );
7662             if(hr == S_OK)
7663             {
7664                 /* This will load the temp file via the XSL */
7665                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7666                 ok(hr == S_OK, "ret %08x\n", hr );
7667                 if(hr == S_OK)
7668                 {
7669                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7670                     SysFreeString(sResult);
7671                 }
7672
7673                 IXMLDOMNode_Release(pNode);
7674             }
7675         }
7676
7677         SysFreeString(sXSL);
7678     }
7679
7680     IXMLDOMDocument_Release(doc);
7681     IXMLDOMDocument_Release(xsl);
7682
7683     DeleteFile(lpPathBuffer);
7684     free_bstrs();
7685 }
7686
7687 static void test_put_nodeValue(void)
7688 {
7689     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7690     IXMLDOMDocument *doc;
7691     IXMLDOMText *text;
7692     IXMLDOMEntityReference *entityref;
7693     IXMLDOMAttribute *attr;
7694     IXMLDOMNode *node;
7695     HRESULT hr;
7696     VARIANT data, type;
7697
7698     doc = create_document(&IID_IXMLDOMDocument);
7699     if (!doc) return;
7700
7701     /* test for unsupported types */
7702     /* NODE_DOCUMENT */
7703     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7704     ok(hr == S_OK, "ret %08x\n", hr );
7705     V_VT(&data) = VT_BSTR;
7706     V_BSTR(&data) = _bstr_("one two three");
7707     hr = IXMLDOMNode_put_nodeValue(node, data);
7708     ok(hr == E_FAIL, "ret %08x\n", hr );
7709     IXMLDOMNode_Release(node);
7710
7711     /* NODE_DOCUMENT_FRAGMENT */
7712     V_VT(&type) = VT_I1;
7713     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7714     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7715     ok(hr == S_OK, "ret %08x\n", hr );
7716     V_VT(&data) = VT_BSTR;
7717     V_BSTR(&data) = _bstr_("one two three");
7718     hr = IXMLDOMNode_put_nodeValue(node, data);
7719     ok(hr == E_FAIL, "ret %08x\n", hr );
7720     IXMLDOMNode_Release(node);
7721
7722     /* NODE_ELEMENT */
7723     V_VT(&type) = VT_I1;
7724     V_I1(&type) = NODE_ELEMENT;
7725     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7726     ok(hr == S_OK, "ret %08x\n", hr );
7727     V_VT(&data) = VT_BSTR;
7728     V_BSTR(&data) = _bstr_("one two three");
7729     hr = IXMLDOMNode_put_nodeValue(node, data);
7730     ok(hr == E_FAIL, "ret %08x\n", hr );
7731     IXMLDOMNode_Release(node);
7732
7733     /* NODE_ENTITY_REFERENCE */
7734     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7735     ok(hr == S_OK, "ret %08x\n", hr );
7736
7737     V_VT(&data) = VT_BSTR;
7738     V_BSTR(&data) = _bstr_("one two three");
7739     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7740     ok(hr == E_FAIL, "ret %08x\n", hr );
7741
7742     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7743     ok(hr == S_OK, "ret %08x\n", hr );
7744     V_VT(&data) = VT_BSTR;
7745     V_BSTR(&data) = _bstr_("one two three");
7746     hr = IXMLDOMNode_put_nodeValue(node, data);
7747     ok(hr == E_FAIL, "ret %08x\n", hr );
7748     IXMLDOMNode_Release(node);
7749     IXMLDOMEntityReference_Release(entityref);
7750
7751     /* supported types */
7752     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7753     ok(hr == S_OK, "ret %08x\n", hr );
7754     V_VT(&data) = VT_BSTR;
7755     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7756     hr = IXMLDOMText_put_nodeValue(text, data);
7757     ok(hr == S_OK, "ret %08x\n", hr );
7758     IXMLDOMText_Release(text);
7759
7760     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7761     ok(hr == S_OK, "ret %08x\n", hr );
7762     V_VT(&data) = VT_BSTR;
7763     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7764     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7765     ok(hr == S_OK, "ret %08x\n", hr );
7766     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7767     ok(hr == S_OK, "ret %08x\n", hr );
7768     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7769         wine_dbgstr_w(V_BSTR(&data)));
7770     VariantClear(&data);
7771     IXMLDOMAttribute_Release(attr);
7772
7773     free_bstrs();
7774
7775     IXMLDOMDocument_Release(doc);
7776 }
7777
7778 static void test_document_IObjectSafety(void)
7779 {
7780     IXMLDOMDocument *doc;
7781     IObjectSafety *safety;
7782     HRESULT hr;
7783
7784     doc = create_document(&IID_IXMLDOMDocument);
7785     if (!doc) return;
7786
7787     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7788     ok(hr == S_OK, "ret %08x\n", hr );
7789
7790     test_IObjectSafety_common(safety);
7791
7792     IObjectSafety_Release(safety);
7793
7794     IXMLDOMDocument_Release(doc);
7795 }
7796
7797 typedef struct _property_test_t {
7798     const GUID *guid;
7799     const char *clsid;
7800     const char *property;
7801     const char *value;
7802 } property_test_t;
7803
7804 static const property_test_t properties_test_data[] = {
7805     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7806     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7807     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7808     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7809     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7810     { 0 }
7811 };
7812
7813 static void test_default_properties(void)
7814 {
7815     const property_test_t *entry = properties_test_data;
7816
7817     while (entry->guid)
7818     {
7819         IXMLDOMDocument2 *doc;
7820         VARIANT var;
7821         HRESULT hr;
7822
7823         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7824         if (hr != S_OK)
7825         {
7826             win_skip("can't create %s instance\n", entry->clsid);
7827             entry++;
7828             continue;
7829         }
7830
7831         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7832         ok(hr == S_OK, "got 0x%08x\n", hr);
7833         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7834            entry->value, entry->clsid);
7835         VariantClear(&var);
7836
7837         IXMLDOMDocument2_Release(doc);
7838
7839         entry++;
7840     }
7841 }
7842
7843 typedef struct {
7844     const char *query;
7845     const char *list;
7846 } xslpattern_test_t;
7847
7848 static const xslpattern_test_t xslpattern_test[] = {
7849     { "root//elem[0]", "E1.E2.D1" },
7850     { "root//elem[index()=1]", "E2.E2.D1" },
7851     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7852     { "root//elem[end()]", "E4.E2.D1" },
7853     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7854     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7855     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7856     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7857     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7858     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7859     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7860     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7861     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7862     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7863     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7864     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7865     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7866     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7867     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7868     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7869     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7870     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7871     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7872     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7873     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7874     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7875     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7876     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7877     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7878     { "root/elem[0]", "E1.E2.D1" },
7879     { "root/elem[index()=1]", "E2.E2.D1" },
7880     { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7881     { "root/elem[end()]", "E4.E2.D1" },
7882     { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7883     { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7884     { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7885     { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7886     { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7887     { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7888     { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7889     { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7890     { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7891     { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7892     { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7893     { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7894     { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7895     { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7896     { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7897     { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7898     { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7899     { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7900     { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7901     { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7902     { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7903     { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7904     { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7905     { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7906     { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7907     { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7908     { NULL }
7909 };
7910
7911 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7912     /* prefixes don't need to be registered, you may use them as they are in the doc */
7913     { "//bar:x", "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7914     /* prefixes must be explicitly specified in the name */
7915     { "//foo:elem", "" },
7916     { "//foo:c", "E3.E4.E2.D1" },
7917     { NULL }
7918 };
7919
7920 static const xslpattern_test_t xslpattern_test_func[] = {
7921     { "attribute()", "" },
7922     { "attribute('depth')", "" },
7923     { "root/attribute('depth')", "A'depth'.E3.D1" },
7924     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7925     { "//x//attribute(id)", NULL },
7926     { "//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" },
7927     { "comment()", "C2.D1" },
7928     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7929     { "element()", "E3.D1" },
7930     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7931     { "//element(a)", NULL },
7932     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7933     { "node()", "P1.D1 C2.D1 E3.D1" },
7934     { "//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" },
7935     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7936     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7937     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7938     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7939     { "pi()", "P1.D1" },
7940     { "//y/pi()", "P1.E4.E3.D1" },
7941     { "root/textnode()", "T2.E3.D1" },
7942     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7943     { NULL }
7944 };
7945
7946 static void test_XSLPattern(void)
7947 {
7948     const xslpattern_test_t *ptr = xslpattern_test;
7949     IXMLDOMDocument2 *doc;
7950     IXMLDOMNodeList *list;
7951     VARIANT_BOOL b;
7952     HRESULT hr;
7953     LONG len;
7954
7955     doc = create_document(&IID_IXMLDOMDocument2);
7956     if (!doc) return;
7957
7958     b = VARIANT_FALSE;
7959     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7960     EXPECT_HR(hr, S_OK);
7961     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7962
7963     /* switch to XSLPattern */
7964     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7965     EXPECT_HR(hr, S_OK);
7966
7967     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7968     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7969     EXPECT_HR(hr, S_OK);
7970
7971     len = 0;
7972     hr = IXMLDOMNodeList_get_length(list, &len);
7973     EXPECT_HR(hr, S_OK);
7974     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7975     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7976     IXMLDOMNodeList_Release(list);
7977
7978     while (ptr->query)
7979     {
7980         list = NULL;
7981         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7982         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7983         len = 0;
7984         hr = IXMLDOMNodeList_get_length(list, &len);
7985         ok(len != 0, "query=%s, empty list\n", ptr->query);
7986         if (len)
7987             expect_list_and_release(list, ptr->list);
7988
7989         ptr++;
7990     }
7991
7992     /* namespace handling */
7993     /* no registered namespaces */
7994     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7995     EXPECT_HR(hr, S_OK);
7996
7997     ptr = xslpattern_test_no_ns;
7998     while (ptr->query)
7999     {
8000         list = NULL;
8001         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8002         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8003
8004         if (*ptr->list)
8005         {
8006             len = 0;
8007             hr = IXMLDOMNodeList_get_length(list, &len);
8008             EXPECT_HR(hr, S_OK);
8009             ok(len != 0, "query=%s, empty list\n", ptr->query);
8010         }
8011         else
8012         {
8013             len = 1;
8014             hr = IXMLDOMNodeList_get_length(list, &len);
8015             EXPECT_HR(hr, S_OK);
8016             ok(len == 0, "query=%s, empty list\n", ptr->query);
8017         }
8018         if (len)
8019             expect_list_and_release(list, ptr->list);
8020
8021         ptr++;
8022     }
8023
8024     /* explicitly register prefix foo */
8025     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
8026
8027     /* now we get the same behavior as XPath */
8028     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8029     EXPECT_HR(hr, S_OK);
8030     len = 0;
8031     hr = IXMLDOMNodeList_get_length(list, &len);
8032     EXPECT_HR(hr, S_OK);
8033     ok(len != 0, "expected filled list\n");
8034     if (len)
8035         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8036
8037     /* set prefix foo to some nonexistent namespace */
8038     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8039     EXPECT_HR(hr, S_OK);
8040
8041     /* the registered prefix takes precedence */
8042     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8043     EXPECT_HR(hr, S_OK);
8044     len = 0;
8045     hr = IXMLDOMNodeList_get_length(list, &len);
8046     EXPECT_HR(hr, S_OK);
8047     ok(len == 0, "expected empty list\n");
8048     IXMLDOMNodeList_Release(list);
8049
8050     IXMLDOMDocument2_Release(doc);
8051
8052     doc = create_document(&IID_IXMLDOMDocument2);
8053     if (!doc) return;
8054
8055     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8056     EXPECT_HR(hr, S_OK);
8057     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8058
8059     ptr = xslpattern_test_func;
8060     while (ptr->query)
8061     {
8062         list = NULL;
8063         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8064         if (ptr->list)
8065         {
8066             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8067             len = 0;
8068             hr = IXMLDOMNodeList_get_length(list, &len);
8069             if (*ptr->list)
8070             {
8071                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8072                 if (len)
8073                     expect_list_and_release(list, ptr->list);
8074             }
8075             else
8076                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8077         }
8078         else
8079             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8080
8081         ptr++;
8082     }
8083
8084     IXMLDOMDocument2_Release(doc);
8085     free_bstrs();
8086 }
8087
8088 static void test_splitText(void)
8089 {
8090     IXMLDOMCDATASection *cdata;
8091     IXMLDOMElement *root;
8092     IXMLDOMDocument *doc;
8093     IXMLDOMText *text, *text2;
8094     IXMLDOMNode *node;
8095     VARIANT var;
8096     VARIANT_BOOL success;
8097     LONG length;
8098     HRESULT hr;
8099
8100     doc = create_document(&IID_IXMLDOMDocument);
8101     if (!doc) return;
8102
8103     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8104     ok(hr == S_OK, "got 0x%08x\n", hr);
8105
8106     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8107     ok(hr == S_OK, "got 0x%08x\n", hr);
8108
8109     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8110     ok(hr == S_OK, "got 0x%08x\n", hr);
8111
8112     V_VT(&var) = VT_EMPTY;
8113     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8114     ok(hr == S_OK, "got 0x%08x\n", hr);
8115
8116     length = 0;
8117     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8118     ok(hr == S_OK, "got 0x%08x\n", hr);
8119     ok(length > 0, "got %d\n", length);
8120
8121     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8122     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8123
8124     text = (void*)0xdeadbeef;
8125     /* negative offset */
8126     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8127     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8128     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8129
8130     text = (void*)0xdeadbeef;
8131     /* offset outside data */
8132     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8133     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8134     ok(text == 0, "got %p\n", text);
8135
8136     text = (void*)0xdeadbeef;
8137     /* offset outside data */
8138     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8139     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8140     ok(text == 0, "got %p\n", text);
8141
8142     /* no empty node created */
8143     node = (void*)0xdeadbeef;
8144     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8145     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8146     ok(node == 0, "got %p\n", text);
8147
8148     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8149     ok(hr == S_OK, "got 0x%08x\n", hr);
8150
8151     length = 0;
8152     hr = IXMLDOMText_get_length(text, &length);
8153     ok(hr == S_OK, "got 0x%08x\n", hr);
8154     ok(length == 7, "got %d\n", length);
8155
8156     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8157     ok(hr == S_OK, "got 0x%08x\n", hr);
8158     IXMLDOMNode_Release(node);
8159
8160     /* split new text node */
8161     hr = IXMLDOMText_get_length(text, &length);
8162     ok(hr == S_OK, "got 0x%08x\n", hr);
8163
8164     node = (void*)0xdeadbeef;
8165     hr = IXMLDOMText_get_nextSibling(text, &node);
8166     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8167     ok(node == 0, "got %p\n", text);
8168
8169     hr = IXMLDOMText_splitText(text, 0, NULL);
8170     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8171
8172     text2 = (void*)0xdeadbeef;
8173     /* negative offset */
8174     hr = IXMLDOMText_splitText(text, -1, &text2);
8175     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8176     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8177
8178     text2 = (void*)0xdeadbeef;
8179     /* offset outside data */
8180     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8181     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8182     ok(text2 == 0, "got %p\n", text2);
8183
8184     text2 = (void*)0xdeadbeef;
8185     /* offset outside data */
8186     hr = IXMLDOMText_splitText(text, length, &text2);
8187     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8188     ok(text2 == 0, "got %p\n", text);
8189
8190     text2 = 0;
8191     hr = IXMLDOMText_splitText(text, 4, &text2);
8192     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8193     if (text2) IXMLDOMText_Release(text2);
8194
8195     node = 0;
8196     hr = IXMLDOMText_get_nextSibling(text, &node);
8197     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8198     if (node) IXMLDOMNode_Release(node);
8199
8200     IXMLDOMText_Release(text);
8201     IXMLDOMElement_Release(root);
8202     IXMLDOMCDATASection_Release(cdata);
8203     free_bstrs();
8204 }
8205
8206 typedef struct {
8207     const char *name;
8208     const char *uri;
8209     HRESULT hr;
8210 } ns_item_t;
8211
8212 /* default_ns_doc used */
8213 static const ns_item_t qualified_item_tests[] = {
8214     { "xml:lang", NULL, S_FALSE },
8215     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8216     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8217     { "ns:b", NULL, S_FALSE },
8218     { "ns:b", "nshref", S_FALSE },
8219     { "b", "nshref", S_OK },
8220     { "d", NULL, S_OK },
8221     { NULL }
8222 };
8223
8224 static const ns_item_t named_item_tests[] = {
8225     { "xml:lang", NULL, S_OK },
8226     { "lang", NULL, S_FALSE },
8227     { "ns:b", NULL, S_OK },
8228     { "b", NULL, S_FALSE },
8229     { "d", NULL, S_OK },
8230     { NULL }
8231 };
8232
8233 static void test_getQualifiedItem(void)
8234 {
8235     IXMLDOMNode *pr_node, *node;
8236     IXMLDOMNodeList *root_list;
8237     IXMLDOMNamedNodeMap *map;
8238     IXMLDOMElement *element;
8239     const ns_item_t* ptr;
8240     IXMLDOMDocument *doc;
8241     VARIANT_BOOL b;
8242     HRESULT hr;
8243     LONG len;
8244
8245     doc = create_document(&IID_IXMLDOMDocument);
8246     if (!doc) return;
8247
8248     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8249     EXPECT_HR(hr, S_OK);
8250     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8251
8252     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8253     EXPECT_HR(hr, S_OK);
8254
8255     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8256     EXPECT_HR(hr, S_OK);
8257
8258     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8259     EXPECT_HR(hr, S_OK);
8260     IXMLDOMNodeList_Release(root_list);
8261
8262     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8263     EXPECT_HR(hr, S_OK);
8264     IXMLDOMNode_Release(pr_node);
8265
8266     len = 0;
8267     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8268     EXPECT_HR(hr, S_OK);
8269     ok( len == 3, "length %d\n", len);
8270
8271     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8272     EXPECT_HR(hr, E_INVALIDARG);
8273
8274     node = (void*)0xdeadbeef;
8275     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8276     EXPECT_HR(hr, E_INVALIDARG);
8277     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8278
8279     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8280     EXPECT_HR(hr, E_INVALIDARG);
8281
8282     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8283     EXPECT_HR(hr, S_OK);
8284
8285     IXMLDOMNode_Release(node);
8286     IXMLDOMNamedNodeMap_Release(map);
8287     IXMLDOMElement_Release(element);
8288
8289     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8290     EXPECT_HR(hr, S_OK);
8291
8292     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8293     EXPECT_HR(hr, S_OK);
8294
8295     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8296     EXPECT_HR(hr, S_OK);
8297     IXMLDOMNode_Release(node);
8298
8299     hr = IXMLDOMElement_get_attributes(element, &map);
8300     EXPECT_HR(hr, S_OK);
8301
8302     ptr = qualified_item_tests;
8303     while (ptr->name)
8304     {
8305        node = (void*)0xdeadbeef;
8306        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8307        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8308        if (hr == S_OK)
8309            IXMLDOMNode_Release(node);
8310        else
8311            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8312        ptr++;
8313     }
8314
8315     ptr = named_item_tests;
8316     while (ptr->name)
8317     {
8318        node = (void*)0xdeadbeef;
8319        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8320        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8321        if (hr == S_OK)
8322            IXMLDOMNode_Release(node);
8323        else
8324            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8325        ptr++;
8326     }
8327
8328     IXMLDOMNamedNodeMap_Release(map);
8329
8330     IXMLDOMElement_Release(element);
8331     IXMLDOMDocument_Release(doc);
8332     free_bstrs();
8333 }
8334
8335 static void test_removeQualifiedItem(void)
8336 {
8337     IXMLDOMDocument *doc;
8338     IXMLDOMElement *element;
8339     IXMLDOMNode *pr_node, *node;
8340     IXMLDOMNodeList *root_list;
8341     IXMLDOMNamedNodeMap *map;
8342     VARIANT_BOOL b;
8343     LONG len;
8344     HRESULT hr;
8345
8346     doc = create_document(&IID_IXMLDOMDocument);
8347     if (!doc) return;
8348
8349     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8350     ok( hr == S_OK, "loadXML failed\n");
8351     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8352
8353     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8354     ok( hr == S_OK, "ret %08x\n", hr);
8355
8356     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8357     ok( hr == S_OK, "ret %08x\n", hr);
8358
8359     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8360     ok( hr == S_OK, "ret %08x\n", hr);
8361     IXMLDOMNodeList_Release(root_list);
8362
8363     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8364     ok( hr == S_OK, "ret %08x\n", hr);
8365     IXMLDOMNode_Release(pr_node);
8366
8367     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8368     ok( hr == S_OK, "ret %08x\n", hr);
8369     ok( len == 3, "length %d\n", len);
8370
8371     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8372     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8373
8374     node = (void*)0xdeadbeef;
8375     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8376     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8377     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8378
8379     /* out pointer is optional */
8380     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8381     ok( hr == S_OK, "ret %08x\n", hr);
8382
8383     /* already removed */
8384     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8385     ok( hr == S_FALSE, "ret %08x\n", hr);
8386
8387     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8388     ok( hr == S_OK, "ret %08x\n", hr);
8389     IXMLDOMNode_Release(node);
8390
8391     IXMLDOMNamedNodeMap_Release( map );
8392     IXMLDOMElement_Release( element );
8393     IXMLDOMDocument_Release( doc );
8394     free_bstrs();
8395 }
8396
8397 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8398 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8399 {
8400     VARIANT_BOOL b;
8401     VARIANT var;
8402     HRESULT hr;
8403
8404     VariantInit(&var);
8405     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8406     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8407     VariantClear(&var);
8408
8409     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8410     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8411     VariantClear(&var);
8412
8413     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8414     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8415
8416     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8417     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8418     VariantClear(&var);
8419 }
8420
8421 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8422 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8423 {
8424     VARIANT_BOOL b;
8425     VARIANT var;
8426
8427     VariantInit(&var);
8428     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8429     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8430     VariantClear(&var);
8431
8432     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8433     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8434     VariantClear(&var);
8435
8436     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8437     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8438
8439     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8440     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8441     VariantClear(&var);
8442 }
8443
8444 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8445 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8446 {
8447     VARIANT var;
8448
8449     VariantInit(&var);
8450     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8451     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8452     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8453     V_VT(&var) = VT_DISPATCH;
8454     V_DISPATCH(&var) = NULL;
8455     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8456     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8457     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8458     VariantClear(&var);
8459 }
8460
8461 #define unset_props(doc) _unset_props(__LINE__, doc)
8462 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8463 {
8464     VARIANT var;
8465
8466     VariantInit(&var);
8467     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8468     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8469     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8470     V_VT(&var) = VT_NULL;
8471     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8472     VariantClear(&var);
8473 }
8474
8475 static void test_get_ownerDocument(void)
8476 {
8477     IXMLDOMDocument *doc1, *doc2, *doc3;
8478     IXMLDOMDocument2 *doc, *doc_owner;
8479     IXMLDOMNode *node;
8480     IXMLDOMSchemaCollection *cache;
8481     VARIANT_BOOL b;
8482     VARIANT var;
8483
8484     doc = create_document(&IID_IXMLDOMDocument2);
8485     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8486     if (!doc || !cache)
8487     {
8488         if (doc) IXMLDOMDocument2_Release(doc);
8489         if (cache) IXMLDOMSchemaCollection_Release(cache);
8490         return;
8491     }
8492
8493     VariantInit(&var);
8494
8495     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8496     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8497
8498     check_default_props(doc);
8499
8500     /* set properties and check that new instances use them */
8501     set_props(doc, cache);
8502     check_set_props(doc);
8503
8504     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8505     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8506
8507     /* new interface keeps props */
8508     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8509     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8510     check_set_props(doc_owner);
8511     IXMLDOMDocument2_Release(doc_owner);
8512
8513     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8514     IXMLDOMNode_Release(node);
8515
8516     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8517
8518     /* reload */
8519     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8520     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8521
8522     /* properties retained even after reload */
8523     check_set_props(doc);
8524
8525     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8526     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8527     IXMLDOMNode_Release(node);
8528
8529     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8530     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8531     check_set_props(doc_owner);
8532
8533     /* changing properties for one instance changes them for all */
8534     unset_props(doc_owner);
8535     check_default_props(doc_owner);
8536     check_default_props(doc);
8537
8538     IXMLDOMSchemaCollection_Release(cache);
8539     IXMLDOMDocument_Release(doc1);
8540     IXMLDOMDocument_Release(doc2);
8541     IXMLDOMDocument_Release(doc3);
8542     IXMLDOMDocument2_Release(doc);
8543     IXMLDOMDocument2_Release(doc_owner);
8544     free_bstrs();
8545 }
8546
8547 static void test_setAttributeNode(void)
8548 {
8549     IXMLDOMDocument *doc, *doc2;
8550     IXMLDOMElement *elem, *elem2;
8551     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8552     VARIANT_BOOL b;
8553     HRESULT hr;
8554     VARIANT v;
8555     BSTR str;
8556     ULONG ref1, ref2;
8557
8558     doc = create_document(&IID_IXMLDOMDocument);
8559     if (!doc) return;
8560
8561     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8562     ok( hr == S_OK, "loadXML failed\n");
8563     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8564
8565     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8566     ok( hr == S_OK, "got 0x%08x\n", hr);
8567
8568     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8569     ok( hr == S_OK, "got 0x%08x\n", hr);
8570     ok( elem2 != elem, "got same instance\n");
8571
8572     ret_attr = (void*)0xdeadbeef;
8573     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8574     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8575     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8576
8577     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8578     ok( hr == S_OK, "got 0x%08x\n", hr);
8579
8580     ref1 = IXMLDOMElement_AddRef(elem);
8581     IXMLDOMElement_Release(elem);
8582
8583     ret_attr = (void*)0xdeadbeef;
8584     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8585     ok( hr == S_OK, "got 0x%08x\n", hr);
8586     ok( ret_attr == NULL, "got %p\n", ret_attr);
8587
8588     /* no reference added */
8589     ref2 = IXMLDOMElement_AddRef(elem);
8590     IXMLDOMElement_Release(elem);
8591     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8592
8593     EXPECT_CHILDREN(elem);
8594     EXPECT_CHILDREN(elem2);
8595
8596     IXMLDOMElement_Release(elem2);
8597
8598     attr2 = NULL;
8599     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8600     ok( hr == S_OK, "got 0x%08x\n", hr);
8601     ok( attr2 != attr, "got same instance %p\n", attr2);
8602     IXMLDOMAttribute_Release(attr2);
8603
8604     /* try to add it another time */
8605     ret_attr = (void*)0xdeadbeef;
8606     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8607     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8608     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8609
8610     IXMLDOMElement_Release(elem);
8611
8612     /* initially used element is released, attribute still 'has' a container */
8613     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8614     ok( hr == S_OK, "got 0x%08x\n", hr);
8615     ret_attr = (void*)0xdeadbeef;
8616     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8617     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8618     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8619     IXMLDOMElement_Release(elem);
8620
8621     /* add attribute already attached to another document */
8622     doc2 = create_document(&IID_IXMLDOMDocument);
8623
8624     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8625     ok( hr == S_OK, "loadXML failed\n");
8626     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8627
8628     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8629     ok( hr == S_OK, "got 0x%08x\n", hr);
8630     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8631     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8632     IXMLDOMElement_Release(elem);
8633
8634     IXMLDOMAttribute_Release(attr);
8635
8636     /* create element, add attribute, see if it's copied or linked */
8637     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8638     ok( hr == S_OK, "got 0x%08x\n", hr);
8639
8640     attr = NULL;
8641     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8642     ok(hr == S_OK, "got 0x%08x\n", hr);
8643     ok(attr != NULL, "got %p\n", attr);
8644
8645     ref1 = IXMLDOMAttribute_AddRef(attr);
8646     IXMLDOMAttribute_Release(attr);
8647
8648     V_VT(&v) = VT_BSTR;
8649     V_BSTR(&v) = _bstr_("attrvalue1");
8650     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8651     ok( hr == S_OK, "got 0x%08x\n", hr);
8652
8653     str = NULL;
8654     hr = IXMLDOMAttribute_get_xml(attr, &str);
8655     ok( hr == S_OK, "got 0x%08x\n", hr);
8656     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8657         "got %s\n", wine_dbgstr_w(str));
8658     SysFreeString(str);
8659
8660     ret_attr = (void*)0xdeadbeef;
8661     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8662     ok(hr == S_OK, "got 0x%08x\n", hr);
8663     ok(ret_attr == NULL, "got %p\n", ret_attr);
8664
8665     /* attribute reference increased */
8666     ref2 = IXMLDOMAttribute_AddRef(attr);
8667     IXMLDOMAttribute_Release(attr);
8668     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8669
8670     hr = IXMLDOMElement_get_xml(elem, &str);
8671     ok( hr == S_OK, "got 0x%08x\n", hr);
8672     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8673         "got %s\n", wine_dbgstr_w(str));
8674     SysFreeString(str);
8675
8676     V_VT(&v) = VT_BSTR;
8677     V_BSTR(&v) = _bstr_("attrvalue2");
8678     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8679     ok( hr == S_OK, "got 0x%08x\n", hr);
8680
8681     hr = IXMLDOMElement_get_xml(elem, &str);
8682     ok( hr == S_OK, "got 0x%08x\n", hr);
8683     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8684         "got %s\n", wine_dbgstr_w(str));
8685     SysFreeString(str);
8686
8687     IXMLDOMElement_Release(elem);
8688     IXMLDOMAttribute_Release(attr);
8689     IXMLDOMDocument_Release(doc2);
8690     IXMLDOMDocument_Release(doc);
8691     free_bstrs();
8692 }
8693
8694 static void test_createNode(void)
8695 {
8696     IXMLDOMDocument *doc;
8697     IXMLDOMElement *elem;
8698     IXMLDOMNode *node;
8699     VARIANT v, var;
8700     BSTR prefix, str;
8701     HRESULT hr;
8702     ULONG ref;
8703
8704     doc = create_document(&IID_IXMLDOMDocument);
8705     if (!doc) return;
8706
8707     EXPECT_REF(doc, 1);
8708
8709     /* reference count tests */
8710     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8711     ok( hr == S_OK, "got 0x%08x\n", hr);
8712
8713     /* initial reference is 2 */
8714 todo_wine {
8715     EXPECT_REF(elem, 2);
8716     ref = IXMLDOMElement_Release(elem);
8717     ok(ref == 1, "got %d\n", ref);
8718     /* it's released already, attempt to release now will crash it */
8719 }
8720
8721     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8722     ok( hr == S_OK, "got 0x%08x\n", hr);
8723     todo_wine EXPECT_REF(elem, 2);
8724     IXMLDOMDocument_Release(doc);
8725     todo_wine EXPECT_REF(elem, 2);
8726     IXMLDOMElement_Release(elem);
8727
8728     doc = create_document(&IID_IXMLDOMDocument);
8729
8730     /* NODE_ELEMENT nodes */
8731     /* 1. specified namespace */
8732     V_VT(&v) = VT_I4;
8733     V_I4(&v) = NODE_ELEMENT;
8734
8735     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8736     ok( hr == S_OK, "got 0x%08x\n", hr);
8737     prefix = NULL;
8738     hr = IXMLDOMNode_get_prefix(node, &prefix);
8739     ok( hr == S_OK, "got 0x%08x\n", hr);
8740     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8741     SysFreeString(prefix);
8742     IXMLDOMNode_Release(node);
8743
8744     /* 2. default namespace */
8745     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8746     ok( hr == S_OK, "got 0x%08x\n", hr);
8747     prefix = (void*)0xdeadbeef;
8748     hr = IXMLDOMNode_get_prefix(node, &prefix);
8749     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8750     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8751     /* check dump */
8752     hr = IXMLDOMNode_get_xml(node, &str);
8753     ok( hr == S_OK, "got 0x%08x\n", hr);
8754     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8755         "got %s\n", wine_dbgstr_w(str));
8756     SysFreeString(str);
8757
8758     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8759     ok( hr == S_OK, "got 0x%08x\n", hr);
8760
8761     V_VT(&var) = VT_BSTR;
8762     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8763     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8764     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8765
8766     str = NULL;
8767     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8768     ok( hr == S_OK, "got 0x%08x\n", hr);
8769     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8770     SysFreeString(str);
8771
8772     IXMLDOMElement_Release(elem);
8773     IXMLDOMNode_Release(node);
8774
8775     IXMLDOMDocument_Release(doc);
8776     free_bstrs();
8777 }
8778
8779 static const char get_prefix_doc[] =
8780     "<?xml version=\"1.0\" ?>"
8781     "<a xmlns:ns1=\"ns1 href\" />";
8782
8783 static void test_get_prefix(void)
8784 {
8785     IXMLDOMDocumentFragment *fragment;
8786     IXMLDOMCDATASection *cdata;
8787     IXMLDOMElement *element;
8788     IXMLDOMComment *comment;
8789     IXMLDOMDocument *doc;
8790     VARIANT_BOOL b;
8791     HRESULT hr;
8792     BSTR str;
8793
8794     doc = create_document(&IID_IXMLDOMDocument);
8795     if (!doc) return;
8796
8797     /* nodes that can't support prefix */
8798     /* 1. document */
8799     str = (void*)0xdeadbeef;
8800     hr = IXMLDOMDocument_get_prefix(doc, &str);
8801     EXPECT_HR(hr, S_FALSE);
8802     ok(str == NULL, "got %p\n", str);
8803
8804     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8805     EXPECT_HR(hr, E_INVALIDARG);
8806
8807     /* 2. cdata */
8808     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8809     ok(hr == S_OK, "got %08x\n", hr );
8810
8811     str = (void*)0xdeadbeef;
8812     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8813     ok(hr == S_FALSE, "got %08x\n", hr);
8814     ok( str == 0, "got %p\n", str);
8815
8816     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8817     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8818     IXMLDOMCDATASection_Release(cdata);
8819
8820     /* 3. comment */
8821     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8822     ok(hr == S_OK, "got %08x\n", hr );
8823
8824     str = (void*)0xdeadbeef;
8825     hr = IXMLDOMComment_get_prefix(comment, &str);
8826     ok(hr == S_FALSE, "got %08x\n", hr);
8827     ok( str == 0, "got %p\n", str);
8828
8829     hr = IXMLDOMComment_get_prefix(comment, NULL);
8830     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8831     IXMLDOMComment_Release(comment);
8832
8833     /* 4. fragment */
8834     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8835     ok(hr == S_OK, "got %08x\n", hr );
8836
8837     str = (void*)0xdeadbeef;
8838     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8839     ok(hr == S_FALSE, "got %08x\n", hr);
8840     ok( str == 0, "got %p\n", str);
8841
8842     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8843     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8844     IXMLDOMDocumentFragment_Release(fragment);
8845
8846     /* no prefix */
8847     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8848     ok( hr == S_OK, "got 0x%08x\n", hr);
8849
8850     hr = IXMLDOMElement_get_prefix(element, NULL);
8851     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8852
8853     str = (void*)0xdeadbeef;
8854     hr = IXMLDOMElement_get_prefix(element, &str);
8855     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8856     ok( str == 0, "got %p\n", str);
8857
8858     IXMLDOMElement_Release(element);
8859
8860     /* with prefix */
8861     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8862     ok( hr == S_OK, "got 0x%08x\n", hr);
8863
8864     str = (void*)0xdeadbeef;
8865     hr = IXMLDOMElement_get_prefix(element, &str);
8866     ok( hr == S_OK, "got 0x%08x\n", hr);
8867     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8868     SysFreeString(str);
8869
8870     str = (void*)0xdeadbeef;
8871     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8872     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8873     ok( str == 0, "got %p\n", str);
8874
8875     IXMLDOMElement_Release(element);
8876
8877     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8878     EXPECT_HR(hr, S_OK);
8879
8880     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8881     EXPECT_HR(hr, S_OK);
8882
8883     str = (void*)0xdeadbeef;
8884     hr = IXMLDOMElement_get_prefix(element, &str);
8885     EXPECT_HR(hr, S_FALSE);
8886     ok(str == NULL, "got %p\n", str);
8887
8888     str = (void*)0xdeadbeef;
8889     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8890     EXPECT_HR(hr, S_FALSE);
8891     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8892
8893     IXMLDOMDocument_Release(doc);
8894     free_bstrs();
8895 }
8896
8897 static void test_selectSingleNode(void)
8898 {
8899     IXMLDOMDocument *doc;
8900     IXMLDOMNodeList *list;
8901     IXMLDOMNode *node;
8902     VARIANT_BOOL b;
8903     HRESULT hr;
8904     LONG len;
8905
8906     doc = create_document(&IID_IXMLDOMDocument);
8907     if (!doc) return;
8908
8909     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8910     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8911
8912     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8913     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8914
8915     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8916     ok( hr == S_OK, "loadXML failed\n");
8917     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8918
8919     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8920     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8921
8922     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8923     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8924
8925     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8926     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8927
8928     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8929     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8930
8931     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8932     ok(hr == S_OK, "got 0x%08x\n", hr);
8933     IXMLDOMNode_Release(node);
8934
8935     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8936     ok(hr == S_OK, "got 0x%08x\n", hr);
8937     IXMLDOMNodeList_Release(list);
8938
8939     list = (void*)0xdeadbeef;
8940     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8941     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8942     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8943
8944     node = (void*)0xdeadbeef;
8945     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8946     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8947     ok(node == 0, "got %p\n", node);
8948
8949     list = (void*)0xdeadbeef;
8950     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8951     ok(hr == S_OK, "got 0x%08x\n", hr);
8952     len = 1;
8953     hr = IXMLDOMNodeList_get_length(list, &len);
8954     ok(hr == S_OK, "got 0x%08x\n", hr);
8955     ok(len == 0, "got %d\n", len);
8956     IXMLDOMNodeList_Release(list);
8957
8958     IXMLDOMDocument_Release(doc);
8959     free_bstrs();
8960 }
8961
8962 static void test_events(void)
8963 {
8964     IConnectionPointContainer *conn;
8965     IConnectionPoint *point;
8966     IXMLDOMDocument *doc;
8967     HRESULT hr;
8968     VARIANT v;
8969     IDispatch *event;
8970
8971     doc = create_document(&IID_IXMLDOMDocument);
8972     if (!doc) return;
8973
8974     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8975     ok(hr == S_OK, "got 0x%08x\n", hr);
8976
8977     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8978     ok(hr == S_OK, "got 0x%08x\n", hr);
8979     IConnectionPoint_Release(point);
8980     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8981     ok(hr == S_OK, "got 0x%08x\n", hr);
8982     IConnectionPoint_Release(point);
8983     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8984     ok(hr == S_OK, "got 0x%08x\n", hr);
8985     IConnectionPoint_Release(point);
8986
8987     IConnectionPointContainer_Release(conn);
8988
8989     /* ready state callback */
8990     VariantInit(&v);
8991     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8992     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8993
8994     event = create_dispevent();
8995     V_VT(&v) = VT_UNKNOWN;
8996     V_UNKNOWN(&v) = (IUnknown*)event;
8997
8998     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8999     ok(hr == S_OK, "got 0x%08x\n", hr);
9000     EXPECT_REF(event, 2);
9001
9002     V_VT(&v) = VT_DISPATCH;
9003     V_DISPATCH(&v) = event;
9004
9005     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9006     ok(hr == S_OK, "got 0x%08x\n", hr);
9007     EXPECT_REF(event, 2);
9008
9009     /* VT_NULL doesn't reset event handler */
9010     V_VT(&v) = VT_NULL;
9011     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9012     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9013     EXPECT_REF(event, 2);
9014
9015     V_VT(&v) = VT_DISPATCH;
9016     V_DISPATCH(&v) = NULL;
9017
9018     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9019     ok(hr == S_OK, "got 0x%08x\n", hr);
9020     EXPECT_REF(event, 1);
9021
9022     V_VT(&v) = VT_UNKNOWN;
9023     V_DISPATCH(&v) = NULL;
9024     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9025     ok(hr == S_OK, "got 0x%08x\n", hr);
9026
9027     IDispatch_Release(event);
9028
9029     IXMLDOMDocument_Release(doc);
9030 }
9031
9032 static void test_createProcessingInstruction(void)
9033 {
9034     static const WCHAR bodyW[] = {'t','e','s','t',0};
9035     IXMLDOMProcessingInstruction *pi;
9036     IXMLDOMDocument *doc;
9037     WCHAR buff[10];
9038     HRESULT hr;
9039
9040     doc = create_document(&IID_IXMLDOMDocument);
9041     if (!doc) return;
9042
9043     /* test for BSTR handling, pass broken BSTR */
9044     memcpy(&buff[2], bodyW, sizeof(bodyW));
9045     /* just a big length */
9046     *(DWORD*)buff = 0xf0f0;
9047     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9048     ok(hr == S_OK, "got 0x%08x\n", hr);
9049
9050     IXMLDOMProcessingInstruction_Release(pi);
9051     IXMLDOMDocument_Release(doc);
9052 }
9053
9054 static void test_put_nodeTypedValue(void)
9055 {
9056     IXMLDOMDocument *doc;
9057     IXMLDOMElement *elem;
9058     VARIANT type;
9059     HRESULT hr;
9060
9061     doc = create_document(&IID_IXMLDOMDocument);
9062     if (!doc) return;
9063
9064     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9065     ok(hr == S_OK, "got 0x%08x\n", hr);
9066
9067     V_VT(&type) = VT_EMPTY;
9068     hr = IXMLDOMElement_get_dataType(elem, &type);
9069     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9070     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9071
9072     /* set typed value for untyped node */
9073     V_VT(&type) = VT_I1;
9074     V_I1(&type) = 1;
9075     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9076     ok(hr == S_OK, "got 0x%08x\n", hr);
9077
9078     V_VT(&type) = VT_EMPTY;
9079     hr = IXMLDOMElement_get_dataType(elem, &type);
9080     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9081     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9082
9083     /* no type info stored */
9084     V_VT(&type) = VT_EMPTY;
9085     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9086     ok(hr == S_OK, "got 0x%08x\n", hr);
9087     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9088     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9089        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9090     VariantClear(&type);
9091
9092     IXMLDOMElement_Release(elem);
9093     IXMLDOMDocument_Release(doc);
9094     free_bstrs();
9095 }
9096
9097 static void test_get_xml(void)
9098 {
9099     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9100     static const char fooA[] = "<foo/>";
9101     IXMLDOMProcessingInstruction *pi;
9102     IXMLDOMNode *first;
9103     IXMLDOMElement *elem = NULL;
9104     IXMLDOMDocument *doc;
9105     VARIANT_BOOL b;
9106     VARIANT v;
9107     BSTR xml;
9108     HRESULT hr;
9109
9110     doc = create_document(&IID_IXMLDOMDocument);
9111     if (!doc) return;
9112
9113     b = VARIANT_TRUE;
9114     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9115     ok(hr == S_OK, "got 0x%08x\n", hr);
9116     ok( b == VARIANT_TRUE, "got %d\n", b);
9117
9118     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9119                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9120     ok(hr == S_OK, "got 0x%08x\n", hr);
9121
9122     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9123     ok(hr == S_OK, "got 0x%08x\n", hr);
9124
9125     V_UNKNOWN(&v) = (IUnknown*)first;
9126     V_VT(&v) = VT_UNKNOWN;
9127
9128     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9129     ok(hr == S_OK, "got 0x%08x\n", hr);
9130
9131     IXMLDOMProcessingInstruction_Release(pi);
9132     IXMLDOMNode_Release(first);
9133
9134     hr = IXMLDOMDocument_get_xml(doc, &xml);
9135     ok(hr == S_OK, "got 0x%08x\n", hr);
9136
9137     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9138         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9139     SysFreeString(xml);
9140
9141     IXMLDOMDocument_Release(doc);
9142
9143     doc = create_document(&IID_IXMLDOMDocument);
9144
9145     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9146     ok(hr == S_OK, "got 0x%08x\n", hr);
9147
9148     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9149     ok(hr == S_OK, "got 0x%08x\n", hr);
9150
9151     hr = IXMLDOMDocument_get_xml(doc, &xml);
9152     ok(hr == S_OK, "got 0x%08x\n", hr);
9153
9154     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9155         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9156     SysFreeString(xml);
9157
9158     IXMLDOMElement_Release(elem);
9159     IXMLDOMDocument_Release(doc);
9160
9161     free_bstrs();
9162 }
9163
9164 static void test_xsltemplate(void)
9165 {
9166     IXSLTemplate *template;
9167     IXSLProcessor *processor;
9168     IXMLDOMDocument *doc, *doc2;
9169     IStream *stream;
9170     VARIANT_BOOL b;
9171     HRESULT hr;
9172     ULONG ref1, ref2;
9173     VARIANT v;
9174
9175     template = create_xsltemplate(&IID_IXSLTemplate);
9176     if (!template) return;
9177
9178     /* works as reset */
9179     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9180     ok(hr == S_OK, "got 0x%08x\n", hr);
9181
9182     doc = create_document(&IID_IXMLDOMDocument);
9183
9184     b = VARIANT_TRUE;
9185     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9186     ok(hr == S_OK, "got 0x%08x\n", hr);
9187     ok( b == VARIANT_TRUE, "got %d\n", b);
9188
9189     /* putref with non-xsl document */
9190     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9191     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9192
9193     b = VARIANT_TRUE;
9194     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9195     ok(hr == S_OK, "got 0x%08x\n", hr);
9196     ok( b == VARIANT_TRUE, "got %d\n", b);
9197
9198     /* not a freethreaded document */
9199     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9200     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9201
9202     IXMLDOMDocument_Release(doc);
9203
9204     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9205     if (hr != S_OK)
9206     {
9207         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9208         IXSLTemplate_Release(template);
9209         return;
9210     }
9211
9212     b = VARIANT_TRUE;
9213     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9214     ok(hr == S_OK, "got 0x%08x\n", hr);
9215     ok( b == VARIANT_TRUE, "got %d\n", b);
9216
9217     /* freethreaded document */
9218     ref1 = IXMLDOMDocument_AddRef(doc);
9219     IXMLDOMDocument_Release(doc);
9220     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9221     ok(hr == S_OK, "got 0x%08x\n", hr);
9222     ref2 = IXMLDOMDocument_AddRef(doc);
9223     IXMLDOMDocument_Release(doc);
9224     ok(ref2 > ref1, "got %d\n", ref2);
9225
9226     /* processor */
9227     hr = IXSLTemplate_createProcessor(template, NULL);
9228     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9229
9230     EXPECT_REF(template, 1);
9231     hr = IXSLTemplate_createProcessor(template, &processor);
9232     ok(hr == S_OK, "got 0x%08x\n", hr);
9233     EXPECT_REF(template, 2);
9234
9235     /* input no set yet */
9236     V_VT(&v) = VT_BSTR;
9237     V_BSTR(&v) = NULL;
9238     hr = IXSLProcessor_get_input(processor, &v);
9239 todo_wine {
9240     ok(hr == S_OK, "got 0x%08x\n", hr);
9241     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9242 }
9243
9244     hr = IXSLProcessor_get_output(processor, NULL);
9245     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9246
9247     /* reset before it was set */
9248     V_VT(&v) = VT_EMPTY;
9249     hr = IXSLProcessor_put_output(processor, v);
9250     ok(hr == S_OK, "got 0x%08x\n", hr);
9251
9252     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9253     EXPECT_REF(stream, 1);
9254
9255     V_VT(&v) = VT_UNKNOWN;
9256     V_UNKNOWN(&v) = (IUnknown*)stream;
9257     hr = IXSLProcessor_put_output(processor, v);
9258     ok(hr == S_OK, "got 0x%08x\n", hr);
9259
9260     /* it seems processor grabs 2 references */
9261     todo_wine EXPECT_REF(stream, 3);
9262
9263     V_VT(&v) = VT_EMPTY;
9264     hr = IXSLProcessor_get_output(processor, &v);
9265     ok(hr == S_OK, "got 0x%08x\n", hr);
9266     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9267     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9268
9269     todo_wine EXPECT_REF(stream, 4);
9270     VariantClear(&v);
9271
9272     hr = IXSLProcessor_transform(processor, NULL);
9273     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9274
9275     /* reset and check stream refcount */
9276     V_VT(&v) = VT_EMPTY;
9277     hr = IXSLProcessor_put_output(processor, v);
9278     ok(hr == S_OK, "got 0x%08x\n", hr);
9279
9280     EXPECT_REF(stream, 1);
9281
9282     IStream_Release(stream);
9283
9284     /* no output interface set, check output */
9285     doc2 = create_document(&IID_IXMLDOMDocument);
9286
9287     b = VARIANT_TRUE;
9288     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9289     ok(hr == S_OK, "got 0x%08x\n", hr);
9290     ok( b == VARIANT_TRUE, "got %d\n", b);
9291
9292     V_VT(&v) = VT_UNKNOWN;
9293     V_UNKNOWN(&v) = (IUnknown*)doc2;
9294     hr = IXSLProcessor_put_input(processor, v);
9295     ok(hr == S_OK, "got 0x%08x\n", hr);
9296
9297     hr = IXSLProcessor_transform(processor, &b);
9298     ok(hr == S_OK, "got 0x%08x\n", hr);
9299
9300     V_VT(&v) = VT_EMPTY;
9301     hr = IXSLProcessor_get_output(processor, &v);
9302     ok(hr == S_OK, "got 0x%08x\n", hr);
9303     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9304     /* we currently output one '\n' instead of empty string */
9305     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9306     IXMLDOMDocument_Release(doc2);
9307     VariantClear(&v);
9308
9309     IXSLProcessor_Release(processor);
9310
9311     /* drop reference */
9312     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9313     ok(hr == S_OK, "got 0x%08x\n", hr);
9314     ref2 = IXMLDOMDocument_AddRef(doc);
9315     IXMLDOMDocument_Release(doc);
9316     ok(ref2 == ref1, "got %d\n", ref2);
9317
9318     IXMLDOMDocument_Release(doc);
9319     IXSLTemplate_Release(template);
9320     free_bstrs();
9321 }
9322
9323 static void test_insertBefore(void)
9324 {
9325     IXMLDOMDocument *doc, *doc2;
9326     IXMLDOMAttribute *attr;
9327     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9328     IXMLDOMNode *node, *newnode;
9329     HRESULT hr;
9330     VARIANT v;
9331     BSTR p;
9332
9333     doc = create_document(&IID_IXMLDOMDocument);
9334
9335     /* insertBefore behaviour for attribute node */
9336     V_VT(&v) = VT_I4;
9337     V_I4(&v) = NODE_ATTRIBUTE;
9338
9339     attr = NULL;
9340     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9341     ok(hr == S_OK, "got 0x%08x\n", hr);
9342     ok(attr != NULL, "got %p\n", attr);
9343
9344     /* attribute to attribute */
9345     V_VT(&v) = VT_I4;
9346     V_I4(&v) = NODE_ATTRIBUTE;
9347     newnode = NULL;
9348     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9349     ok(hr == S_OK, "got 0x%08x\n", hr);
9350     ok(newnode != NULL, "got %p\n", newnode);
9351
9352     V_VT(&v) = VT_NULL;
9353     node = (void*)0xdeadbeef;
9354     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9355     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9356     ok(node == NULL, "got %p\n", node);
9357
9358     V_VT(&v) = VT_UNKNOWN;
9359     V_UNKNOWN(&v) = (IUnknown*)attr;
9360     node = (void*)0xdeadbeef;
9361     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9362     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9363     ok(node == NULL, "got %p\n", node);
9364     IXMLDOMNode_Release(newnode);
9365
9366     /* cdata to attribute */
9367     V_VT(&v) = VT_I4;
9368     V_I4(&v) = NODE_CDATA_SECTION;
9369     newnode = NULL;
9370     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9371     ok(hr == S_OK, "got 0x%08x\n", hr);
9372     ok(newnode != NULL, "got %p\n", newnode);
9373
9374     V_VT(&v) = VT_NULL;
9375     node = (void*)0xdeadbeef;
9376     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9377     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9378     ok(node == NULL, "got %p\n", node);
9379     IXMLDOMNode_Release(newnode);
9380
9381     /* comment to attribute */
9382     V_VT(&v) = VT_I4;
9383     V_I4(&v) = NODE_COMMENT;
9384     newnode = NULL;
9385     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9386     ok(hr == S_OK, "got 0x%08x\n", hr);
9387     ok(newnode != NULL, "got %p\n", newnode);
9388
9389     V_VT(&v) = VT_NULL;
9390     node = (void*)0xdeadbeef;
9391     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9392     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9393     ok(node == NULL, "got %p\n", node);
9394     IXMLDOMNode_Release(newnode);
9395
9396     /* element to attribute */
9397     V_VT(&v) = VT_I4;
9398     V_I4(&v) = NODE_ELEMENT;
9399     newnode = NULL;
9400     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9401     ok(hr == S_OK, "got 0x%08x\n", hr);
9402     ok(newnode != NULL, "got %p\n", newnode);
9403
9404     V_VT(&v) = VT_NULL;
9405     node = (void*)0xdeadbeef;
9406     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9407     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9408     ok(node == NULL, "got %p\n", node);
9409     IXMLDOMNode_Release(newnode);
9410
9411     /* pi to attribute */
9412     V_VT(&v) = VT_I4;
9413     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9414     newnode = NULL;
9415     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9416     ok(hr == S_OK, "got 0x%08x\n", hr);
9417     ok(newnode != NULL, "got %p\n", newnode);
9418
9419     V_VT(&v) = VT_NULL;
9420     node = (void*)0xdeadbeef;
9421     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9422     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9423     ok(node == NULL, "got %p\n", node);
9424     IXMLDOMNode_Release(newnode);
9425     IXMLDOMAttribute_Release(attr);
9426
9427     /* insertBefore for elements */
9428     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9429     ok(hr == S_OK, "got 0x%08x\n", hr);
9430
9431     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9432     ok(hr == S_OK, "got 0x%08x\n", hr);
9433
9434     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9435     ok(hr == S_OK, "got 0x%08x\n", hr);
9436
9437     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9438     ok(hr == S_OK, "got 0x%08x\n", hr);
9439
9440     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9441     ok(hr == S_OK, "got 0x%08x\n", hr);
9442
9443     EXPECT_NO_CHILDREN(elem1);
9444     EXPECT_NO_CHILDREN(elem2);
9445     EXPECT_NO_CHILDREN(elem3);
9446
9447     todo_wine EXPECT_REF(elem2, 2);
9448
9449     V_VT(&v) = VT_DISPATCH;
9450     V_DISPATCH(&v) = NULL;
9451     node = NULL;
9452     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9453     ok(hr == S_OK, "got 0x%08x\n", hr);
9454     ok(node == (void*)elem4, "got %p\n", node);
9455
9456     EXPECT_CHILDREN(elem1);
9457     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9458     EXPECT_HR(hr, S_OK);
9459     IXMLDOMElement_Release(elem4);
9460
9461     EXPECT_NO_CHILDREN(elem1);
9462
9463     V_VT(&v) = VT_NULL;
9464     node = NULL;
9465     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9466     ok(hr == S_OK, "got 0x%08x\n", hr);
9467     ok(node == (void*)elem2, "got %p\n", node);
9468
9469     EXPECT_CHILDREN(elem1);
9470     todo_wine EXPECT_REF(elem2, 3);
9471     IXMLDOMNode_Release(node);
9472
9473     /* again for already linked node */
9474     V_VT(&v) = VT_NULL;
9475     node = NULL;
9476     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9477     ok(hr == S_OK, "got 0x%08x\n", hr);
9478     ok(node == (void*)elem2, "got %p\n", node);
9479
9480     EXPECT_CHILDREN(elem1);
9481
9482     /* increments each time */
9483     todo_wine EXPECT_REF(elem2, 3);
9484     IXMLDOMNode_Release(node);
9485
9486     /* try to add to another element */
9487     V_VT(&v) = VT_NULL;
9488     node = (void*)0xdeadbeef;
9489     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9490     ok(hr == S_OK, "got 0x%08x\n", hr);
9491     ok(node == (void*)elem2, "got %p\n", node);
9492
9493     EXPECT_CHILDREN(elem3);
9494     EXPECT_NO_CHILDREN(elem1);
9495
9496     IXMLDOMNode_Release(node);
9497
9498     /* cross document case - try to add as child to a node created with other doc */
9499     doc2 = create_document(&IID_IXMLDOMDocument);
9500
9501     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9502     ok(hr == S_OK, "got 0x%08x\n", hr);
9503     todo_wine EXPECT_REF(elem4, 2);
9504
9505     /* same name, another instance */
9506     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9507     ok(hr == S_OK, "got 0x%08x\n", hr);
9508     todo_wine EXPECT_REF(elem5, 2);
9509
9510     todo_wine EXPECT_REF(elem3, 2);
9511     V_VT(&v) = VT_NULL;
9512     node = NULL;
9513     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9514     ok(hr == S_OK, "got 0x%08x\n", hr);
9515     ok(node == (void*)elem4, "got %p\n", node);
9516     todo_wine EXPECT_REF(elem4, 3);
9517     todo_wine EXPECT_REF(elem3, 2);
9518     IXMLDOMNode_Release(node);
9519
9520     V_VT(&v) = VT_NULL;
9521     node = NULL;
9522     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9523     ok(hr == S_OK, "got 0x%08x\n", hr);
9524     ok(node == (void*)elem5, "got %p\n", node);
9525     todo_wine EXPECT_REF(elem4, 2);
9526     todo_wine EXPECT_REF(elem5, 3);
9527     IXMLDOMNode_Release(node);
9528
9529     IXMLDOMDocument_Release(doc2);
9530
9531     IXMLDOMElement_Release(elem1);
9532     IXMLDOMElement_Release(elem2);
9533     IXMLDOMElement_Release(elem3);
9534     IXMLDOMElement_Release(elem4);
9535     IXMLDOMElement_Release(elem5);
9536
9537     /* elements with same default namespace */
9538     V_VT(&v) = VT_I4;
9539     V_I4(&v) = NODE_ELEMENT;
9540     elem1 = NULL;
9541     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9542     ok(hr == S_OK, "got 0x%08x\n", hr);
9543     ok(elem1 != NULL, "got %p\n", elem1);
9544
9545     V_VT(&v) = VT_I4;
9546     V_I4(&v) = NODE_ELEMENT;
9547     elem2 = NULL;
9548     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9549     ok(hr == S_OK, "got 0x%08x\n", hr);
9550     ok(elem2 != NULL, "got %p\n", elem2);
9551
9552     /* check contents so far */
9553     p = NULL;
9554     hr = IXMLDOMElement_get_xml(elem1, &p);
9555     ok(hr == S_OK, "got 0x%08x\n", hr);
9556     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9557     SysFreeString(p);
9558
9559     p = NULL;
9560     hr = IXMLDOMElement_get_xml(elem2, &p);
9561     ok(hr == S_OK, "got 0x%08x\n", hr);
9562     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9563     SysFreeString(p);
9564
9565     V_VT(&v) = VT_NULL;
9566     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9567     ok(hr == S_OK, "got 0x%08x\n", hr);
9568
9569     /* get_xml depends on context, for top node it omits child namespace attribute,
9570        but at child level it's still returned */
9571     p = NULL;
9572     hr = IXMLDOMElement_get_xml(elem1, &p);
9573     ok(hr == S_OK, "got 0x%08x\n", hr);
9574     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9575         "got %s\n", wine_dbgstr_w(p));
9576     SysFreeString(p);
9577
9578     p = NULL;
9579     hr = IXMLDOMElement_get_xml(elem2, &p);
9580     ok(hr == S_OK, "got 0x%08x\n", hr);
9581     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9582     SysFreeString(p);
9583
9584     IXMLDOMElement_Release(elem1);
9585     IXMLDOMElement_Release(elem2);
9586
9587     /* child without default namespace added to node with default namespace */
9588     V_VT(&v) = VT_I4;
9589     V_I4(&v) = NODE_ELEMENT;
9590     elem1 = NULL;
9591     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9592     ok(hr == S_OK, "got 0x%08x\n", hr);
9593     ok(elem1 != NULL, "got %p\n", elem1);
9594
9595     V_VT(&v) = VT_I4;
9596     V_I4(&v) = NODE_ELEMENT;
9597     elem2 = NULL;
9598     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9599     ok(hr == S_OK, "got 0x%08x\n", hr);
9600     ok(elem2 != NULL, "got %p\n", elem2);
9601
9602     EXPECT_REF(elem2, 1);
9603     V_VT(&v) = VT_NULL;
9604     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9605     ok(hr == S_OK, "got 0x%08x\n", hr);
9606     EXPECT_REF(elem2, 1);
9607
9608     p = NULL;
9609     hr = IXMLDOMElement_get_xml(elem2, &p);
9610     ok(hr == S_OK, "got 0x%08x\n", hr);
9611     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9612     SysFreeString(p);
9613
9614     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9615     ok(hr == S_OK, "got 0x%08x\n", hr);
9616
9617     p = NULL;
9618     hr = IXMLDOMElement_get_xml(elem2, &p);
9619     ok(hr == S_OK, "got 0x%08x\n", hr);
9620     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9621     SysFreeString(p);
9622
9623     IXMLDOMElement_Release(elem1);
9624     IXMLDOMElement_Release(elem2);
9625     IXMLDOMDocument_Release(doc);
9626 }
9627
9628 static void test_appendChild(void)
9629 {
9630     IXMLDOMDocument *doc, *doc2;
9631     IXMLDOMElement *elem, *elem2;
9632     HRESULT hr;
9633
9634     doc = create_document(&IID_IXMLDOMDocument);
9635     doc2 = create_document(&IID_IXMLDOMDocument);
9636
9637     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9638     ok(hr == S_OK, "got 0x%08x\n", hr);
9639
9640     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9641     ok(hr == S_OK, "got 0x%08x\n", hr);
9642
9643     EXPECT_REF(doc, 1);
9644     todo_wine EXPECT_REF(elem, 2);
9645     EXPECT_REF(doc2, 1);
9646     todo_wine EXPECT_REF(elem2, 2);
9647     EXPECT_NO_CHILDREN(doc);
9648     EXPECT_NO_CHILDREN(doc2);
9649
9650     /* append from another document */
9651     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9652     ok(hr == S_OK, "got 0x%08x\n", hr);
9653
9654     EXPECT_REF(doc, 1);
9655     todo_wine EXPECT_REF(elem, 2);
9656     EXPECT_REF(doc2, 1);
9657     todo_wine EXPECT_REF(elem2, 2);
9658     EXPECT_NO_CHILDREN(doc);
9659     EXPECT_CHILDREN(doc2);
9660
9661     IXMLDOMElement_Release(elem);
9662     IXMLDOMElement_Release(elem2);
9663     IXMLDOMDocument_Release(doc);
9664     IXMLDOMDocument_Release(doc2);
9665 }
9666
9667 static void test_get_doctype(void)
9668 {
9669     IXMLDOMDocumentType *doctype;
9670     IXMLDOMDocument *doc;
9671     HRESULT hr;
9672
9673     doc = create_document(&IID_IXMLDOMDocument);
9674
9675     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9676     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9677
9678     doctype = (void*)0xdeadbeef;
9679     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9680     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9681     ok(doctype == NULL, "got %p\n", doctype);
9682
9683     IXMLDOMDocument_Release(doc);
9684 }
9685
9686 static void test_get_tagName(void)
9687 {
9688     IXMLDOMDocument *doc;
9689     IXMLDOMElement *elem, *elem2;
9690     HRESULT hr;
9691     BSTR str;
9692
9693     doc = create_document(&IID_IXMLDOMDocument);
9694
9695     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9696     ok(hr == S_OK, "got 0x%08x\n", hr);
9697
9698     hr = IXMLDOMElement_get_tagName(elem, NULL);
9699     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9700
9701     str = NULL;
9702     hr = IXMLDOMElement_get_tagName(elem, &str);
9703     ok(hr == S_OK, "got 0x%08x\n", hr);
9704     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9705     SysFreeString(str);
9706
9707     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9708     ok(hr == S_OK, "got 0x%08x\n", hr);
9709
9710     str = NULL;
9711     hr = IXMLDOMElement_get_tagName(elem2, &str);
9712     ok(hr == S_OK, "got 0x%08x\n", hr);
9713     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9714     SysFreeString(str);
9715
9716     IXMLDOMDocument_Release(elem);
9717     IXMLDOMDocument_Release(elem2);
9718     IXMLDOMDocument_Release(doc);
9719     free_bstrs();
9720 }
9721
9722 typedef struct {
9723     DOMNodeType type;
9724     const char *name;
9725     VARTYPE vt;
9726     HRESULT hr;
9727 } node_type_t;
9728
9729 static const node_type_t get_datatype[] = {
9730     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9731     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9732     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9733     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9734     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9735     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9736     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9737     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9738     { 0 }
9739 };
9740
9741 static void test_get_dataType(void)
9742 {
9743     const node_type_t *entry = get_datatype;
9744     IXMLDOMDocument *doc;
9745
9746     doc = create_document(&IID_IXMLDOMDocument);
9747
9748     while (entry->type)
9749     {
9750         IXMLDOMNode *node = NULL;
9751         VARIANT var, type;
9752         HRESULT hr;
9753
9754         V_VT(&var) = VT_I4;
9755         V_I4(&var) = entry->type;
9756         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9757         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9758
9759         hr = IXMLDOMNode_get_dataType(node, NULL);
9760         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9761
9762         VariantInit(&type);
9763         hr = IXMLDOMNode_get_dataType(node, &type);
9764         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9765             hr, entry->hr, entry->type);
9766         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9767             V_VT(&type), entry->vt, entry->type);
9768         VariantClear(&type);
9769
9770         IXMLDOMNode_Release(node);
9771
9772         entry++;
9773     }
9774
9775     IXMLDOMDocument_Release(doc);
9776     free_bstrs();
9777 }
9778
9779 typedef struct _get_node_typestring_t {
9780     DOMNodeType type;
9781     const char *string;
9782 } get_node_typestring_t;
9783
9784 static const get_node_typestring_t get_node_typestring[] = {
9785     { NODE_ELEMENT,                "element"               },
9786     { NODE_ATTRIBUTE,              "attribute"             },
9787     { NODE_TEXT,                   "text"                  },
9788     { NODE_CDATA_SECTION ,         "cdatasection"          },
9789     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9790     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9791     { NODE_COMMENT,                "comment"               },
9792     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9793     { 0 }
9794 };
9795
9796 static void test_get_nodeTypeString(void)
9797 {
9798     const get_node_typestring_t *entry = get_node_typestring;
9799     IXMLDOMDocument *doc;
9800     HRESULT hr;
9801     BSTR str;
9802
9803     doc = create_document(&IID_IXMLDOMDocument);
9804
9805     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9806     ok(hr == S_OK, "got 0x%08x\n", hr);
9807     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9808     SysFreeString(str);
9809
9810     while (entry->type)
9811     {
9812         IXMLDOMNode *node = NULL;
9813         VARIANT var;
9814
9815         V_VT(&var) = VT_I4;
9816         V_I4(&var) = entry->type;
9817         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9818         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9819
9820         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9821         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9822
9823         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9824         ok(hr == S_OK, "got 0x%08x\n", hr);
9825         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9826             wine_dbgstr_w(str), entry->string, entry->type);
9827         SysFreeString(str);
9828         IXMLDOMNode_Release(node);
9829
9830         entry++;
9831     }
9832
9833     IXMLDOMDocument_Release(doc);
9834     free_bstrs();
9835 }
9836
9837 typedef struct _get_attributes_t {
9838     DOMNodeType type;
9839     HRESULT hr;
9840 } get_attributes_t;
9841
9842 static const get_attributes_t get_attributes[] = {
9843     { NODE_ATTRIBUTE,              S_FALSE },
9844     { NODE_TEXT,                   S_FALSE },
9845     { NODE_CDATA_SECTION ,         S_FALSE },
9846     { NODE_ENTITY_REFERENCE,       S_FALSE },
9847     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9848     { NODE_COMMENT,                S_FALSE },
9849     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9850     { 0 }
9851 };
9852
9853 static void test_get_attributes(void)
9854 {
9855     const get_attributes_t *entry = get_attributes;
9856     IXMLDOMNamedNodeMap *map;
9857     IXMLDOMDocument *doc;
9858     IXMLDOMNode *node, *node2;
9859     VARIANT_BOOL b;
9860     HRESULT hr;
9861     BSTR str;
9862     LONG length;
9863
9864     doc = create_document(&IID_IXMLDOMDocument);
9865
9866     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9867     ok(hr == S_OK, "got %08x\n", hr);
9868
9869     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9870     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9871
9872     map = (void*)0xdeadbeef;
9873     hr = IXMLDOMDocument_get_attributes(doc, &map);
9874     ok(hr == S_FALSE, "got %08x\n", hr);
9875     ok(map == NULL, "got %p\n", map);
9876
9877     /* first child is <?xml ?> */
9878     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9879     ok(hr == S_OK, "got %08x\n", hr);
9880
9881     hr = IXMLDOMNode_get_attributes(node, &map);
9882     ok(hr == S_OK, "got %08x\n", hr);
9883
9884     length = -1;
9885     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9886     EXPECT_HR(hr, S_OK);
9887     todo_wine ok(length == 1, "got %d\n", length);
9888
9889     if (hr == S_OK && length == 1)
9890     {
9891         IXMLDOMAttribute *attr;
9892         DOMNodeType type;
9893         VARIANT v;
9894
9895         node2 = NULL;
9896         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9897         EXPECT_HR(hr, S_OK);
9898         ok(node != NULL, "got %p\n", node2);
9899
9900         hr = IXMLDOMNode_get_nodeName(node2, &str);
9901         EXPECT_HR(hr, S_OK);
9902         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9903         SysFreeString(str);
9904
9905         length = -1;
9906         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9907         EXPECT_HR(hr, S_OK);
9908         ok(length == 1, "got %d\n", length);
9909
9910         type = -1;
9911         hr = IXMLDOMNode_get_nodeType(node2, &type);
9912         EXPECT_HR(hr, S_OK);
9913         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9914
9915         hr = IXMLDOMNode_get_xml(node, &str);
9916         EXPECT_HR(hr, S_OK);
9917         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9918         SysFreeString(str);
9919
9920         hr = IXMLDOMNode_get_text(node, &str);
9921         EXPECT_HR(hr, S_OK);
9922         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9923         SysFreeString(str);
9924
9925         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9926         EXPECT_HR(hr, S_OK);
9927
9928         length = -1;
9929         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9930         EXPECT_HR(hr, S_OK);
9931         ok(length == 0, "got %d\n", length);
9932
9933         hr = IXMLDOMNode_get_xml(node, &str);
9934         EXPECT_HR(hr, S_OK);
9935         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9936         SysFreeString(str);
9937
9938         hr = IXMLDOMNode_get_text(node, &str);
9939         EXPECT_HR(hr, S_OK);
9940         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9941         SysFreeString(str);
9942
9943         IXMLDOMNamedNodeMap_Release(map);
9944
9945         hr = IXMLDOMNode_get_attributes(node, &map);
9946         ok(hr == S_OK, "got %08x\n", hr);
9947
9948         length = -1;
9949         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9950         EXPECT_HR(hr, S_OK);
9951         ok(length == 0, "got %d\n", length);
9952
9953         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9954         EXPECT_HR(hr, S_OK);
9955
9956         V_VT(&v) = VT_BSTR;
9957         V_BSTR(&v) = _bstr_("UTF-8");
9958         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9959         EXPECT_HR(hr, S_OK);
9960
9961         EXPECT_REF(attr, 2);
9962         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9963         EXPECT_HR(hr, S_OK);
9964         EXPECT_REF(attr, 2);
9965
9966         hr = IXMLDOMNode_get_attributes(node, &map);
9967         ok(hr == S_OK, "got %08x\n", hr);
9968
9969         length = -1;
9970         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9971         EXPECT_HR(hr, S_OK);
9972         ok(length == 1, "got %d\n", length);
9973
9974         hr = IXMLDOMNode_get_xml(node, &str);
9975         EXPECT_HR(hr, S_OK);
9976         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9977         SysFreeString(str);
9978
9979         hr = IXMLDOMNode_get_text(node, &str);
9980         EXPECT_HR(hr, S_OK);
9981         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9982         SysFreeString(str);
9983
9984         IXMLDOMNamedNodeMap_Release(map);
9985         IXMLDOMNode_Release(node2);
9986     }
9987
9988     IXMLDOMNode_Release(node);
9989
9990     /* last child is element */
9991     EXPECT_REF(doc, 1);
9992     hr = IXMLDOMDocument_get_lastChild(doc, &node);
9993     ok(hr == S_OK, "got %08x\n", hr);
9994     EXPECT_REF(doc, 1);
9995
9996     EXPECT_REF(node, 1);
9997     hr = IXMLDOMNode_get_attributes(node, &map);
9998     ok(hr == S_OK, "got %08x\n", hr);
9999     EXPECT_REF(node, 1);
10000     EXPECT_REF(doc, 1);
10001
10002     EXPECT_REF(map, 1);
10003     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10004     ok(hr == S_OK, "got %08x\n", hr);
10005     EXPECT_REF(node, 1);
10006     EXPECT_REF(node2, 1);
10007     EXPECT_REF(map, 1);
10008     EXPECT_REF(doc, 1);
10009     IXMLDOMNode_Release(node2);
10010
10011     /* release node before map release, map still works */
10012     IXMLDOMNode_Release(node);
10013
10014     length = 0;
10015     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10016     ok(hr == S_OK, "got %08x\n", hr);
10017     ok(length == 1, "got %d\n", length);
10018
10019     node2 = NULL;
10020     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10021     ok(hr == S_OK, "got %08x\n", hr);
10022     EXPECT_REF(node2, 1);
10023     IXMLDOMNode_Release(node2);
10024
10025     IXMLDOMNamedNodeMap_Release(map);
10026
10027     while (entry->type)
10028     {
10029         VARIANT var;
10030
10031         node = NULL;
10032
10033         V_VT(&var) = VT_I4;
10034         V_I4(&var) = entry->type;
10035         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10036         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10037
10038         hr = IXMLDOMNode_get_attributes(node, NULL);
10039         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10040
10041         map = (void*)0xdeadbeef;
10042         hr = IXMLDOMNode_get_attributes(node, &map);
10043         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10044             hr, entry->hr, entry->type);
10045         ok(map == NULL, "got %p\n", map);
10046
10047         IXMLDOMNode_Release(node);
10048
10049         entry++;
10050     }
10051
10052     IXMLDOMDocument_Release(doc);
10053     free_bstrs();
10054 }
10055
10056 static void test_selection(void)
10057 {
10058     IXMLDOMSelection *selection, *selection2;
10059     IEnumVARIANT *enum1, *enum2, *enum3;
10060     IXMLDOMNodeList *list;
10061     IXMLDOMDocument *doc;
10062     IDispatchEx *dispex;
10063     IXMLDOMNode *node;
10064     IDispatch *disp;
10065     VARIANT_BOOL b;
10066     HRESULT hr;
10067     DISPID did;
10068     VARIANT v;
10069     BSTR name;
10070     ULONG ret;
10071     LONG len;
10072
10073     doc = create_document(&IID_IXMLDOMDocument);
10074
10075     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
10076     EXPECT_HR(hr, S_OK);
10077
10078     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10079     EXPECT_HR(hr, S_OK);
10080
10081     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10082     EXPECT_HR(hr, S_OK);
10083     IXMLDOMSelection_Release(selection);
10084
10085     /* collection disp id */
10086     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10087     EXPECT_HR(hr, S_OK);
10088     did = 0;
10089     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10090     EXPECT_HR(hr, S_OK);
10091     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10092     len = 0;
10093     hr = IXMLDOMSelection_get_length(selection, &len);
10094     EXPECT_HR(hr, S_OK);
10095     ok(len == 1, "got %d\n", len);
10096     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10097     EXPECT_HR(hr, S_OK);
10098     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10099     IDispatchEx_Release(dispex);
10100
10101     /* IEnumVARIANT tests */
10102     enum1 = NULL;
10103     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10104     EXPECT_HR(hr, S_OK);
10105     ok(enum1 != NULL, "got %p\n", enum1);
10106     EXPECT_REF(enum1, 2);
10107
10108     enum3 = NULL;
10109     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10110     EXPECT_HR(hr, S_OK);
10111     ok(enum3 != NULL, "got %p\n", enum3);
10112     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10113     EXPECT_REF(enum1, 3);
10114     IEnumVARIANT_Release(enum3);
10115
10116     EXPECT_REF(selection, 1);
10117     EXPECT_REF(enum1, 2);
10118
10119     enum2 = NULL;
10120     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10121     EXPECT_HR(hr, S_OK);
10122     ok(enum2 != NULL, "got %p\n", enum2);
10123
10124     EXPECT_REF(selection, 2);
10125     EXPECT_REF(enum1, 2);
10126     EXPECT_REF(enum2, 1);
10127
10128     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10129
10130     selection2 = NULL;
10131     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10132     EXPECT_HR(hr, S_OK);
10133     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10134     EXPECT_REF(selection, 3);
10135     EXPECT_REF(enum1, 2);
10136
10137     IXMLDOMSelection_Release(selection2);
10138
10139     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10140     EXPECT_HR(hr, S_OK);
10141     EXPECT_REF(selection, 3);
10142     IDispatch_Release(disp);
10143
10144     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10145     EXPECT_HR(hr, S_OK);
10146     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10147     EXPECT_REF(selection, 2);
10148     EXPECT_REF(enum1, 3);
10149
10150     IEnumVARIANT_Release(enum1);
10151     IEnumVARIANT_Release(enum2);
10152
10153     enum1 = NULL;
10154     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10155     EXPECT_HR(hr, S_OK);
10156     ok(enum1 != NULL, "got %p\n", enum1);
10157     EXPECT_REF(enum1, 1);
10158     EXPECT_REF(selection, 2);
10159
10160     enum2 = NULL;
10161     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10162     EXPECT_HR(hr, S_OK);
10163     ok(enum2 != NULL, "got %p\n", enum2);
10164     EXPECT_REF(enum2, 1);
10165     EXPECT_REF(selection, 3);
10166
10167     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10168
10169     IEnumVARIANT_AddRef(enum1);
10170     EXPECT_REF(selection, 3);
10171     EXPECT_REF(enum1, 2);
10172     EXPECT_REF(enum2, 1);
10173     IEnumVARIANT_Release(enum1);
10174
10175     IEnumVARIANT_Release(enum1);
10176     IEnumVARIANT_Release(enum2);
10177
10178     EXPECT_REF(selection, 1);
10179
10180     IXMLDOMNodeList_Release(list);
10181
10182     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10183     EXPECT_HR(hr, S_OK);
10184
10185     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10186     EXPECT_HR(hr, E_NOINTERFACE);
10187
10188     IXMLDOMNodeList_Release(list);
10189
10190     /* test if IEnumVARIANT touches selection context */
10191     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10192     EXPECT_HR(hr, S_OK);
10193
10194     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10195     EXPECT_HR(hr, S_OK);
10196
10197     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10198     EXPECT_HR(hr, S_OK);
10199
10200     len = 0;
10201     hr = IXMLDOMSelection_get_length(selection, &len);
10202     EXPECT_HR(hr, S_OK);
10203     ok(len == 4, "got %d\n", len);
10204
10205     enum1 = NULL;
10206     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10207     EXPECT_HR(hr, S_OK);
10208
10209     /* no-op if zero count */
10210     V_VT(&v) = VT_I2;
10211     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10212     EXPECT_HR(hr, S_OK);
10213     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10214
10215     /* positive count, null array pointer */
10216     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10217     EXPECT_HR(hr, E_INVALIDARG);
10218
10219     ret = 1;
10220     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10221     EXPECT_HR(hr, E_INVALIDARG);
10222     ok(ret == 0, "got %d\n", ret);
10223
10224     V_VT(&v) = VT_I2;
10225     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10226     EXPECT_HR(hr, S_OK);
10227     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10228
10229     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10230     EXPECT_HR(hr, S_OK);
10231     hr = IXMLDOMNode_get_nodeName(node, &name);
10232     EXPECT_HR(hr, S_OK);
10233     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10234     SysFreeString(name);
10235     IXMLDOMNode_Release(node);
10236     VariantClear(&v);
10237
10238     /* list cursor is updated */
10239     hr = IXMLDOMSelection_nextNode(selection, &node);
10240     EXPECT_HR(hr, S_OK);
10241     hr = IXMLDOMNode_get_nodeName(node, &name);
10242     EXPECT_HR(hr, S_OK);
10243     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10244     IXMLDOMNode_Release(node);
10245
10246     V_VT(&v) = VT_I2;
10247     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10248     EXPECT_HR(hr, S_OK);
10249     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10250     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10251     EXPECT_HR(hr, S_OK);
10252     hr = IXMLDOMNode_get_nodeName(node, &name);
10253     EXPECT_HR(hr, S_OK);
10254     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10255     SysFreeString(name);
10256     IXMLDOMNode_Release(node);
10257     VariantClear(&v);
10258
10259     hr = IXMLDOMSelection_nextNode(selection, &node);
10260     EXPECT_HR(hr, S_OK);
10261     hr = IXMLDOMNode_get_nodeName(node, &name);
10262     EXPECT_HR(hr, S_OK);
10263     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10264     IXMLDOMNode_Release(node);
10265
10266     IXMLDOMSelection_Release(selection);
10267     IXMLDOMNodeList_Release(list);
10268     IXMLDOMDocument_Release(doc);
10269
10270     free_bstrs();
10271 }
10272
10273 static void test_load(void)
10274 {
10275     IXMLDOMDocument *doc;
10276     IXMLDOMNodeList *list;
10277     VARIANT_BOOL b;
10278     HANDLE hfile;
10279     VARIANT src;
10280     HRESULT hr;
10281     BOOL ret;
10282     BSTR path, bstr1, bstr2;
10283     DWORD written;
10284     void* ptr;
10285
10286     /* prepare a file */
10287     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10288     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10289     if(hfile == INVALID_HANDLE_VALUE) return;
10290
10291     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10292     ok(ret, "WriteFile failed\n");
10293
10294     CloseHandle(hfile);
10295
10296     doc = create_document(&IID_IXMLDOMDocument);
10297
10298     path = _bstr_("test.xml");
10299
10300     /* load from path: VT_BSTR */
10301     V_VT(&src) = VT_BSTR;
10302     V_BSTR(&src) = path;
10303     hr = IXMLDOMDocument_load(doc, src, &b);
10304     EXPECT_HR(hr, S_OK);
10305     ok(b == VARIANT_TRUE, "got %d\n", b);
10306
10307     /* load from a path: VT_BSTR|VT_BYREF */
10308     V_VT(&src) = VT_BSTR | VT_BYREF;
10309     V_BSTRREF(&src) = &path;
10310     hr = IXMLDOMDocument_load(doc, src, &b);
10311     EXPECT_HR(hr, S_OK);
10312     ok(b == VARIANT_TRUE, "got %d\n", b);
10313
10314     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10315     V_VT(&src) = VT_BSTR | VT_BYREF;
10316     V_BSTRREF(&src) = NULL;
10317     hr = IXMLDOMDocument_load(doc, src, &b);
10318     EXPECT_HR(hr, E_INVALIDARG);
10319     ok(b == VARIANT_FALSE, "got %d\n", b);
10320
10321     IXMLDOMDocument_Release(doc);
10322
10323     DeleteFileA("test.xml");
10324
10325     doc = create_document(&IID_IXMLDOMDocument);
10326
10327     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10328     EXPECT_HR(hr, S_OK);
10329     ok(b == VARIANT_TRUE, "got %d\n", b);
10330
10331     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10332     EXPECT_HR(hr, S_OK);
10333     bstr1 = _bstr_(list_to_string(list));
10334
10335     hr = IXMLDOMNodeList_reset(list);
10336     EXPECT_HR(hr, S_OK);
10337
10338     IXMLDOMDocument_Release(doc);
10339
10340     doc = create_document(&IID_IXMLDOMDocument);
10341
10342     VariantInit(&src);
10343     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
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, szExampleXML, lstrlenA(szExampleXML));
10352     hr = SafeArrayUnlock(V_ARRAY(&src));
10353     EXPECT_HR(hr, S_OK);
10354
10355     hr = IXMLDOMDocument_load(doc, src, &b);
10356     EXPECT_HR(hr, S_OK);
10357     ok(b == VARIANT_TRUE, "got %d\n", b);
10358
10359     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10360     EXPECT_HR(hr, S_OK);
10361     bstr2 = _bstr_(list_to_string(list));
10362
10363     hr = IXMLDOMNodeList_reset(list);
10364     EXPECT_HR(hr, S_OK);
10365
10366     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10367        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10368
10369     IXMLDOMDocument_Release(doc);
10370     IXMLDOMNodeList_Release(list);
10371     VariantClear(&src);
10372
10373     /* UTF-16 isn't accepted */
10374     doc = create_document(&IID_IXMLDOMDocument);
10375
10376     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10377     V_VT(&src) = VT_ARRAY|VT_UI1;
10378     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10379     ptr = NULL;
10380     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10381     EXPECT_HR(hr, S_OK);
10382     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10383
10384     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10385     hr = SafeArrayUnlock(V_ARRAY(&src));
10386     EXPECT_HR(hr, S_OK);
10387
10388     hr = IXMLDOMDocument_load(doc, src, &b);
10389     todo_wine EXPECT_HR(hr, S_FALSE);
10390     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10391
10392     VariantClear(&src);
10393
10394     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10395     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10396     V_VT(&src) = VT_ARRAY|VT_UI2;
10397     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10398     ptr = NULL;
10399     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10400     EXPECT_HR(hr, S_OK);
10401     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10402
10403     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10404     hr = SafeArrayUnlock(V_ARRAY(&src));
10405     EXPECT_HR(hr, S_OK);
10406
10407     hr = IXMLDOMDocument_load(doc, src, &b);
10408     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10409     ok(b == VARIANT_FALSE, "got %d\n", b);
10410
10411     VariantClear(&src);
10412     IXMLDOMDocument_Release(doc);
10413
10414     free_bstrs();
10415 }
10416
10417 static void test_domobj_dispex(IUnknown *obj)
10418 {
10419     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10420     IDispatchEx *dispex;
10421     IUnknown *unk;
10422     DWORD props;
10423     UINT ticnt;
10424     HRESULT hr;
10425     BSTR name;
10426
10427     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10428     EXPECT_HR(hr, S_OK);
10429     if (FAILED(hr)) return;
10430
10431     ticnt = 0;
10432     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10433     EXPECT_HR(hr, S_OK);
10434     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10435
10436     name = SysAllocString(szstar);
10437     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10438     EXPECT_HR(hr, E_NOTIMPL);
10439     SysFreeString(name);
10440
10441     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10442     EXPECT_HR(hr, E_NOTIMPL);
10443
10444     props = 0;
10445     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10446     EXPECT_HR(hr, E_NOTIMPL);
10447     ok(props == 0, "expected 0 got %d\n", props);
10448
10449     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10450     EXPECT_HR(hr, E_NOTIMPL);
10451     if (SUCCEEDED(hr)) SysFreeString(name);
10452
10453     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10454     EXPECT_HR(hr, E_NOTIMPL);
10455
10456     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10457     EXPECT_HR(hr, E_NOTIMPL);
10458     if (hr == S_OK && unk) IUnknown_Release(unk);
10459
10460     IDispatchEx_Release(dispex);
10461 }
10462
10463 static void test_mxnamespacemanager(void)
10464 {
10465     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10466     IVBMXNamespaceManager *mgr2;
10467     IMXNamespaceManager *nsmgr;
10468     WCHAR buffW[250];
10469     IDispatch *disp;
10470     IUnknown *unk;
10471     HRESULT hr;
10472     INT len;
10473
10474     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10475         &IID_IMXNamespaceManager, (void**)&nsmgr);
10476     EXPECT_HR(hr, S_OK);
10477
10478     /* IMXNamespaceManager inherits from IUnknown */
10479     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10480     EXPECT_HR(hr, S_OK);
10481     IDispatch_Release(disp);
10482
10483     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10484     EXPECT_HR(hr, S_OK);
10485     IVBMXNamespaceManager_Release(mgr2);
10486
10487     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10488     EXPECT_HR(hr, S_OK);
10489
10490     /* prefix already added */
10491     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10492     EXPECT_HR(hr, S_FALSE);
10493
10494     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10495     EXPECT_HR(hr, E_INVALIDARG);
10496
10497     /* "xml" and "xmlns" are not allowed here */
10498     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10499     EXPECT_HR(hr, E_INVALIDARG);
10500
10501     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10502     EXPECT_HR(hr, E_INVALIDARG);
10503 todo_wine {
10504     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10505     EXPECT_HR(hr, E_FAIL);
10506 }
10507     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10508     EXPECT_HR(hr, E_POINTER);
10509
10510     len = -1;
10511     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10512     EXPECT_HR(hr, S_OK);
10513     ok(len == 3, "got %d\n", len);
10514
10515     len = -1;
10516     buffW[0] = 0x1;
10517     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10518     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10519     ok(len == -1, "got %d\n", len);
10520     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10521
10522     len = 10;
10523     buffW[0] = 0x1;
10524     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10525     EXPECT_HR(hr, S_OK);
10526     ok(len == 3, "got %d\n", len);
10527     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10528
10529     /* getURI */
10530     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10531     EXPECT_HR(hr, E_INVALIDARG);
10532
10533     len = -1;
10534     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10535     EXPECT_HR(hr, E_INVALIDARG);
10536     ok(len == -1, "got %d\n", len);
10537
10538     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10539     EXPECT_HR(hr, E_POINTER);
10540
10541     len = -1;
10542     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10543     EXPECT_HR(hr, S_OK);
10544     /* length of "xml" uri is constant */
10545     ok(len == strlen(xmluriA), "got %d\n", len);
10546
10547     len = 100;
10548     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10549     EXPECT_HR(hr, S_OK);
10550     ok(len == strlen(xmluriA), "got %d\n", len);
10551     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10552
10553     len = strlen(xmluriA)-1;
10554     buffW[0] = 0x1;
10555     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10556     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10557     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10558     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10559
10560     /* prefix xml1 not defined */
10561     len = -1;
10562     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10563     EXPECT_HR(hr, S_FALSE);
10564     ok(len == 0, "got %d\n", len);
10565
10566     len = 100;
10567     buffW[0] = 0x1;
10568     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10569     EXPECT_HR(hr, S_FALSE);
10570     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10571     ok(len == 0, "got %d\n", len);
10572
10573     /* IDispatchEx tests */
10574     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10575     EXPECT_HR(hr, S_OK);
10576     test_domobj_dispex(unk);
10577     IUnknown_Release(unk);
10578
10579     IMXNamespaceManager_Release(nsmgr);
10580
10581     /* ::getPrefix() */
10582     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10583         &IID_IMXNamespaceManager, (void**)&nsmgr);
10584     EXPECT_HR(hr, S_OK);
10585
10586     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10587     EXPECT_HR(hr, E_INVALIDARG);
10588
10589     len = -1;
10590     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10591     EXPECT_HR(hr, E_INVALIDARG);
10592     ok(len == -1, "got %d\n", len);
10593
10594     len = 100;
10595     buffW[0] = 0x1;
10596     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10597     EXPECT_HR(hr, E_FAIL);
10598     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10599     ok(len == 100, "got %d\n", len);
10600
10601     len = 0;
10602     buffW[0] = 0x1;
10603     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10604     EXPECT_HR(hr, E_FAIL);
10605     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10606     ok(len == 0, "got %d\n", len);
10607
10608     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10609     EXPECT_HR(hr, S_OK);
10610
10611     len = 100;
10612     buffW[0] = 0x1;
10613     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10614     EXPECT_HR(hr, S_OK);
10615     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10616     ok(len == 3, "got %d\n", len);
10617
10618     len = 100;
10619     buffW[0] = 0x1;
10620     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10621     EXPECT_HR(hr, S_OK);
10622     ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10623     ok(len == 3, "got %d\n", len);
10624
10625     /* with null buffer it's possible to get required length */
10626     len = 100;
10627     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10628     EXPECT_HR(hr, S_OK);
10629     ok(len == 3, "got %d\n", len);
10630
10631     len = 0;
10632     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10633     EXPECT_HR(hr, S_OK);
10634     ok(len == 3, "got %d\n", len);
10635
10636     len = 100;
10637     buffW[0] = 0x1;
10638     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10639     EXPECT_HR(hr, E_FAIL);
10640     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10641     ok(len == 100, "got %d\n", len);
10642
10643     len = 100;
10644     buffW[0] = 0x1;
10645     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10646     EXPECT_HR(hr, E_FAIL);
10647     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10648     ok(len == 100, "got %d\n", len);
10649
10650     len = 100;
10651     buffW[0] = 0x1;
10652     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10653     EXPECT_HR(hr, E_INVALIDARG);
10654     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10655     ok(len == 100, "got %d\n", len);
10656
10657     len = 100;
10658     buffW[0] = 0x1;
10659     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10660     EXPECT_HR(hr, E_INVALIDARG);
10661     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10662     ok(len == 100, "got %d\n", len);
10663
10664     len = 100;
10665     buffW[0] = 0x1;
10666     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10667     EXPECT_HR(hr, E_INVALIDARG);
10668     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10669     ok(len == 100, "got %d\n", len);
10670
10671     len = 100;
10672     buffW[0] = 0x1;
10673     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10674     EXPECT_HR(hr, E_FAIL);
10675     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10676     ok(len == 100, "got %d\n", len);
10677
10678     len = 100;
10679     buffW[0] = 0x1;
10680     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10681     EXPECT_HR(hr, E_INVALIDARG);
10682     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10683     ok(len == 100, "got %d\n", len);
10684
10685     /* declare another one, indices are shifted */
10686     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10687     EXPECT_HR(hr, S_OK);
10688
10689     len = 100;
10690     buffW[0] = 0x1;
10691     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10692     EXPECT_HR(hr, S_OK);
10693     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10694     ok(len == 3, "got %d\n", len);
10695
10696     len = 100;
10697     buffW[0] = 0x1;
10698     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10699     EXPECT_HR(hr, S_OK);
10700     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10701     ok(len == 3, "got %d\n", len);
10702
10703     len = 100;
10704     buffW[0] = 0x1;
10705     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10706     EXPECT_HR(hr, E_FAIL);
10707     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10708     ok(len == 100, "got %d\n", len);
10709
10710     len = 100;
10711     buffW[0] = 0x1;
10712     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10713     EXPECT_HR(hr, E_INVALIDARG);
10714     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10715     ok(len == 100, "got %d\n", len);
10716
10717     IMXNamespaceManager_Release(nsmgr);
10718
10719     free_bstrs();
10720 }
10721
10722 static void test_mxnamespacemanager_override(void)
10723 {
10724     IMXNamespaceManager *nsmgr;
10725     WCHAR buffW[250];
10726     VARIANT_BOOL b;
10727     HRESULT hr;
10728     INT len;
10729
10730     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10731         &IID_IMXNamespaceManager, (void**)&nsmgr);
10732     EXPECT_HR(hr, S_OK);
10733
10734     len = sizeof(buffW)/sizeof(WCHAR);
10735     buffW[0] = 0;
10736     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10737     EXPECT_HR(hr, S_OK);
10738     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10739
10740     len = sizeof(buffW)/sizeof(WCHAR);
10741     buffW[0] = 0;
10742     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10743     EXPECT_HR(hr, E_FAIL);
10744
10745     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10746     EXPECT_HR(hr, E_POINTER);
10747
10748     b = VARIANT_FALSE;
10749     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10750     EXPECT_HR(hr, S_OK);
10751     ok(b == VARIANT_TRUE, "got %d\n", b);
10752
10753     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10754     EXPECT_HR(hr, S_OK);
10755
10756     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10757     EXPECT_HR(hr, S_OK);
10758
10759     len = sizeof(buffW)/sizeof(WCHAR);
10760     buffW[0] = 0;
10761     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10762     EXPECT_HR(hr, S_OK);
10763     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10764
10765     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10766     EXPECT_HR(hr, S_OK);
10767
10768     len = sizeof(buffW)/sizeof(WCHAR);
10769     buffW[0] = 0;
10770     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10771     EXPECT_HR(hr, S_OK);
10772     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10773
10774     len = sizeof(buffW)/sizeof(WCHAR);
10775     buffW[0] = 0;
10776     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10777     EXPECT_HR(hr, S_OK);
10778     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10779
10780     len = sizeof(buffW)/sizeof(WCHAR);
10781     buffW[0] = 0;
10782     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10783     EXPECT_HR(hr, S_OK);
10784     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10785
10786     /* new prefix placed at index 1 always */
10787     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10788     EXPECT_HR(hr, S_OK);
10789
10790     len = sizeof(buffW)/sizeof(WCHAR);
10791     buffW[0] = 0;
10792     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10793     EXPECT_HR(hr, S_OK);
10794     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10795
10796     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10797     todo_wine EXPECT_HR(hr, E_FAIL);
10798
10799     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10800     EXPECT_HR(hr, E_FAIL);
10801
10802     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10803     EXPECT_HR(hr, E_FAIL);
10804
10805     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10806     EXPECT_HR(hr, S_OK);
10807
10808     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10809     EXPECT_HR(hr, S_FALSE);
10810
10811     len = sizeof(buffW)/sizeof(WCHAR);
10812     buffW[0] = 0;
10813     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10814     EXPECT_HR(hr, S_OK);
10815     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10816
10817     len = sizeof(buffW)/sizeof(WCHAR);
10818     buffW[0] = 0;
10819     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10820     EXPECT_HR(hr, S_OK);
10821     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10822
10823     IMXNamespaceManager_Release(nsmgr);
10824
10825     free_bstrs();
10826 }
10827
10828 static const DOMNodeType nodetypes_test[] =
10829 {
10830     NODE_ELEMENT,
10831     NODE_ATTRIBUTE,
10832     NODE_TEXT,
10833     NODE_CDATA_SECTION,
10834     NODE_ENTITY_REFERENCE,
10835     NODE_PROCESSING_INSTRUCTION,
10836     NODE_COMMENT,
10837     NODE_DOCUMENT_FRAGMENT,
10838     NODE_INVALID
10839 };
10840
10841 static void test_dispex(void)
10842 {
10843     const DOMNodeType *type = nodetypes_test;
10844     IXMLDOMImplementation *impl;
10845     IXMLDOMNodeList *node_list;
10846     IXMLDOMParseError *error;
10847     IXMLDOMNamedNodeMap *map;
10848     IXSLProcessor *processor;
10849     IXSLTemplate *template;
10850     IXMLDOMDocument *doc;
10851     IXMLHTTPRequest *req;
10852     IXMLDOMElement *elem;
10853     IDispatchEx *dispex;
10854     IXMLDOMNode *node;
10855     VARIANT_BOOL b;
10856     IUnknown *unk;
10857     HRESULT hr;
10858     DISPID did;
10859
10860     doc = create_document(&IID_IXMLDOMDocument);
10861
10862     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10863     test_domobj_dispex(unk);
10864     IUnknown_Release(unk);
10865
10866     for(; *type != NODE_INVALID; type++)
10867     {
10868         IXMLDOMNode *node;
10869         VARIANT v;
10870
10871         V_VT(&v) = VT_I2;
10872         V_I2(&v) = *type;
10873
10874         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10875         ok(hr == S_OK, "failed to create node type %d\n", *type);
10876
10877         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10878
10879         test_domobj_dispex(unk);
10880         IUnknown_Release(unk);
10881         IXMLDOMNode_Release(node);
10882     }
10883
10884     /* IXMLDOMNodeList */
10885     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10886     EXPECT_HR(hr, S_OK);
10887     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10888     test_domobj_dispex(unk);
10889     IUnknown_Release(unk);
10890     IXMLDOMNodeList_Release(node_list);
10891
10892     /* IXMLDOMNodeList for children list */
10893     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10894     EXPECT_HR(hr, S_OK);
10895     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10896     test_domobj_dispex(unk);
10897     IUnknown_Release(unk);
10898
10899     /* collection dispex test, empty collection */
10900     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10901     EXPECT_HR(hr, S_OK);
10902     did = 0;
10903     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10904     EXPECT_HR(hr, S_OK);
10905     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10906     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10907     EXPECT_HR(hr, S_OK);
10908     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10909     IDispatchEx_Release(dispex);
10910
10911     IXMLDOMNodeList_Release(node_list);
10912
10913     /* IXMLDOMParseError */
10914     hr = IXMLDOMDocument_get_parseError(doc, &error);
10915     EXPECT_HR(hr, S_OK);
10916     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
10917     test_domobj_dispex(unk);
10918     IUnknown_Release(unk);
10919     IXMLDOMParseError_Release(error);
10920
10921     /* IXMLDOMNamedNodeMap */
10922     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10923     EXPECT_HR(hr, S_OK);
10924
10925     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
10926     EXPECT_HR(hr, S_OK);
10927     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10928     EXPECT_HR(hr, S_OK);
10929     IXMLDOMNodeList_Release(node_list);
10930
10931     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10932     EXPECT_HR(hr, S_OK);
10933     IXMLDOMNode_Release(node);
10934     hr = IXMLDOMElement_get_attributes(elem, &map);
10935     EXPECT_HR(hr, S_OK);
10936     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
10937     test_domobj_dispex(unk);
10938     IUnknown_Release(unk);
10939     /* collection dispex test */
10940     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10941     EXPECT_HR(hr, S_OK);
10942     did = 0;
10943     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10944     EXPECT_HR(hr, S_OK);
10945     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10946     IDispatchEx_Release(dispex);
10947
10948     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
10949     EXPECT_HR(hr, S_OK);
10950     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
10951     EXPECT_HR(hr, S_OK);
10952     IXMLDOMNodeList_Release(node_list);
10953     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
10954     EXPECT_HR(hr, S_OK);
10955     IXMLDOMNode_Release(node);
10956     hr = IXMLDOMElement_get_attributes(elem, &map);
10957     EXPECT_HR(hr, S_OK);
10958     /* collection dispex test, empty collection */
10959     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
10960     EXPECT_HR(hr, S_OK);
10961     did = 0;
10962     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10963     EXPECT_HR(hr, S_OK);
10964     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10965     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10966     EXPECT_HR(hr, S_OK);
10967     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10968     IDispatchEx_Release(dispex);
10969
10970     IXMLDOMNamedNodeMap_Release(map);
10971     IXMLDOMElement_Release(elem);
10972
10973     /* IXMLDOMImplementation */
10974     hr = IXMLDOMDocument_get_implementation(doc, &impl);
10975     EXPECT_HR(hr, S_OK);
10976
10977     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
10978     EXPECT_HR(hr, S_OK);
10979     IDispatchEx_Release(dispex);
10980     IXMLDOMImplementation_Release(impl);
10981
10982     IXMLDOMDocument_Release(doc);
10983
10984     /* IXMLHTTPRequest */
10985     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
10986         &IID_IXMLHttpRequest, (void**)&req);
10987     if (hr == S_OK)
10988     {
10989         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
10990         EXPECT_HR(hr, E_NOINTERFACE);
10991         IXMLHTTPRequest_Release(req);
10992     }
10993
10994     /* IXSLTemplate */
10995     template = create_xsltemplate(&IID_IXSLTemplate);
10996     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
10997     EXPECT_HR(hr, S_OK);
10998     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
10999     EXPECT_HR(hr, S_OK);
11000     test_domobj_dispex(unk);
11001     IUnknown_Release(unk);
11002     IDispatchEx_Release(dispex);
11003
11004     /* IXSLProcessor */
11005     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11006     EXPECT_HR(hr, S_OK);
11007     b = VARIANT_FALSE;
11008     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11009     EXPECT_HR(hr, S_OK);
11010     ok(b == VARIANT_TRUE, "got %d\n", b);
11011
11012     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11013     EXPECT_HR(hr, S_OK);
11014     IXMLDOMDocument_Release(doc);
11015
11016     hr = IXSLTemplate_createProcessor(template, &processor);
11017     EXPECT_HR(hr, S_OK);
11018     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11019     EXPECT_HR(hr, S_OK);
11020     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11021     EXPECT_HR(hr, S_OK);
11022     test_domobj_dispex(unk);
11023     IUnknown_Release(unk);
11024     IDispatchEx_Release(dispex);
11025
11026     IXSLProcessor_Release(processor);
11027     IXSLTemplate_Release(template);
11028
11029     free_bstrs();
11030 }
11031
11032 static void test_parseerror(void)
11033 {
11034     IXMLDOMParseError2 *error2;
11035     IXMLDOMParseError *error;
11036     IXMLDOMDocument *doc;
11037     HRESULT hr;
11038
11039     doc = create_document(&IID_IXMLDOMDocument);
11040
11041     hr = IXMLDOMDocument_get_parseError(doc, &error);
11042     EXPECT_HR(hr, S_OK);
11043
11044     hr = IXMLDOMParseError_get_line(error, NULL);
11045     EXPECT_HR(hr, E_INVALIDARG);
11046
11047     hr = IXMLDOMParseError_get_srcText(error, NULL);
11048     EXPECT_HR(hr, E_INVALIDARG);
11049
11050     hr = IXMLDOMParseError_get_linepos(error, NULL);
11051     EXPECT_HR(hr, E_INVALIDARG);
11052
11053     IXMLDOMParseError_Release(error);
11054     IXMLDOMDocument_Release(doc);
11055
11056     doc = create_document_version(60, &IID_IXMLDOMDocument);
11057     if (!doc) return;
11058     hr = IXMLDOMDocument_get_parseError(doc, &error);
11059     EXPECT_HR(hr, S_OK);
11060     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11061     EXPECT_HR(hr, S_OK);
11062     IXMLDOMParseError2_Release(error2);
11063     IXMLDOMParseError_Release(error);
11064     IXMLDOMDocument_Release(doc);
11065 }
11066
11067 static void test_getAttributeNode(void)
11068 {
11069     IXMLDOMAttribute *attr;
11070     IXMLDOMDocument *doc;
11071     IXMLDOMElement *elem;
11072     VARIANT_BOOL v;
11073     HRESULT hr;
11074     BSTR str;
11075
11076     doc = create_document(&IID_IXMLDOMDocument);
11077
11078     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11079     EXPECT_HR(hr, S_OK);
11080
11081     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11082     EXPECT_HR(hr, S_OK);
11083
11084     str = SysAllocString(nonexistent_fileW);
11085     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11086     EXPECT_HR(hr, E_FAIL);
11087
11088     attr = (IXMLDOMAttribute*)0xdeadbeef;
11089     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11090     EXPECT_HR(hr, E_FAIL);
11091     ok(attr == NULL, "got %p\n", attr);
11092     SysFreeString(str);
11093
11094     str = SysAllocString(nonexistent_attrW);
11095     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11096     EXPECT_HR(hr, S_FALSE);
11097
11098     attr = (IXMLDOMAttribute*)0xdeadbeef;
11099     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11100     EXPECT_HR(hr, S_FALSE);
11101     ok(attr == NULL, "got %p\n", attr);
11102     SysFreeString(str);
11103
11104     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11105     EXPECT_HR(hr, S_OK);
11106     IXMLDOMAttribute_Release(attr);
11107
11108     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11109     EXPECT_HR(hr, S_FALSE);
11110
11111     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11112     EXPECT_HR(hr, S_OK);
11113     IXMLDOMAttribute_Release(attr);
11114
11115     IXMLDOMElement_Release(elem);
11116     IXMLDOMDocument_Release(doc);
11117     free_bstrs();
11118 }
11119
11120 typedef struct {
11121     DOMNodeType type;
11122     const char *name;
11123     REFIID iids[3];
11124 } supporterror_t;
11125
11126 static const supporterror_t supporterror_test[] = {
11127     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11128     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11129     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11130     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11131     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11132     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11133     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11134     { NODE_INVALID }
11135 };
11136
11137 static void test_supporterrorinfo(void)
11138 {
11139     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11140                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11141     const supporterror_t *ptr = supporterror_test;
11142     ISupportErrorInfo *errorinfo, *info2;
11143     IXMLDOMNamedNodeMap *map, *map2;
11144     IXMLDOMDocument *doc;
11145     IXMLDOMElement *elem;
11146     VARIANT_BOOL b;
11147     IUnknown *unk;
11148     REFIID *iid;
11149     void *dummy;
11150     HRESULT hr;
11151
11152     doc = create_document_version(60, &IID_IXMLDOMDocument3);
11153     if (!doc) return;
11154
11155     EXPECT_REF(doc, 1);
11156     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11157     EXPECT_HR(hr, S_OK);
11158     EXPECT_REF(doc, 1);
11159     ISupportErrorInfo_AddRef(errorinfo);
11160     EXPECT_REF(errorinfo, 2);
11161     EXPECT_REF(doc, 1);
11162     ISupportErrorInfo_Release(errorinfo);
11163
11164     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11165     EXPECT_HR(hr, S_OK);
11166     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11167
11168     /* error interface can't be queried back for DOM interface */
11169     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11170     EXPECT_HR(hr, E_NOINTERFACE);
11171     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11172     EXPECT_HR(hr, E_NOINTERFACE);
11173
11174     ISupportErrorInfo_Release(info2);
11175
11176     iid = iids;
11177     while (*iid)
11178     {
11179         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11180         EXPECT_HR(hr, S_OK);
11181         if (hr == S_OK)
11182         {
11183             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11184             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11185             IUnknown_Release(unk);
11186         }
11187
11188         iid++;
11189     }
11190
11191     ISupportErrorInfo_Release(errorinfo);
11192
11193     while (ptr->type != NODE_INVALID)
11194     {
11195         IXMLDOMNode *node;
11196         VARIANT type;
11197
11198         V_VT(&type) = VT_I1;
11199         V_I1(&type) = ptr->type;
11200
11201         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11202         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11203
11204         EXPECT_REF(node, 1);
11205         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11206         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11207         EXPECT_REF(node, 1);
11208
11209         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11210         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11211
11212         iid = ptr->iids;
11213
11214         while (*iid)
11215         {
11216             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11217             if (hr == S_OK)
11218             {
11219                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11220                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11221                 IUnknown_Release(unk);
11222             }
11223
11224             iid++;
11225         }
11226
11227         ISupportErrorInfo_Release(errorinfo);
11228         IXMLDOMNode_Release(node);
11229         ptr++;
11230     }
11231
11232     /* IXMLDOMNamedNodeMap */
11233     b = VARIANT_FALSE;
11234     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11235     EXPECT_HR(hr, S_OK);
11236     ok(b == VARIANT_TRUE, "got %d\n", b);
11237
11238     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11239     EXPECT_HR(hr, S_OK);
11240
11241     hr = IXMLDOMElement_get_attributes(elem, &map);
11242     EXPECT_HR(hr, S_OK);
11243
11244     EXPECT_REF(map, 1);
11245     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11246     EXPECT_HR(hr, S_OK);
11247     EXPECT_REF(map, 2);
11248
11249     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11250     EXPECT_HR(hr, S_OK);
11251
11252     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11253     EXPECT_HR(hr, S_OK);
11254     ok(map == map2, "got %p\n", map2);
11255     IXMLDOMNamedNodeMap_Release(map2);
11256
11257     EXPECT_REF(errorinfo, 2);
11258     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11259     EXPECT_HR(hr, S_OK);
11260     EXPECT_REF(errorinfo, 3);
11261     EXPECT_REF(map, 3);
11262     IUnknown_Release(unk);
11263
11264     ISupportErrorInfo_Release(errorinfo);
11265     IXMLDOMNamedNodeMap_Release(map);
11266     IXMLDOMElement_Release(elem);
11267
11268     IXMLDOMDocument_Release(doc);
11269     free_bstrs();
11270 }
11271
11272 typedef struct {
11273     DOMNodeType type;
11274     const char *name;
11275     const char *put_content;
11276     HRESULT put_hr;
11277     VARTYPE get_vt;
11278     HRESULT get_hr;
11279 } node_value_t;
11280
11281 static const node_value_t nodevalue_test[] = {
11282     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11283     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11284     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11285     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11286     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11287     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11288     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11289     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11290     { NODE_INVALID }
11291 };
11292
11293 static void test_nodeValue(void)
11294 {
11295     const node_value_t *ptr = nodevalue_test;
11296     IXMLDOMDocument *doc;
11297     HRESULT hr;
11298
11299     doc = create_document(&IID_IXMLDOMDocument);
11300     if (!doc) return;
11301
11302     while (ptr->type != NODE_INVALID)
11303     {
11304         IXMLDOMNode *node;
11305         VARIANT v;
11306
11307         V_VT(&v) = VT_I2;
11308         V_I2(&v) = ptr->type;
11309
11310         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11311         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11312
11313         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11314         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11315
11316         V_VT(&v) = VT_BSTR;
11317         V_BSTR(&v) = _bstr_(ptr->put_content);
11318         hr = IXMLDOMNode_put_nodeValue(node, v);
11319         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11320
11321         V_VT(&v) = VT_EMPTY;
11322         hr = IXMLDOMNode_get_nodeValue(node, &v);
11323         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11324         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11325         if (hr == S_OK)
11326             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11327                 wine_dbgstr_w(V_BSTR(&v)));
11328         VariantClear(&v);
11329
11330         IXMLDOMNode_Release(node);
11331
11332         ptr++;
11333     }
11334
11335     IXMLDOMDocument_Release(doc);
11336 }
11337
11338 static const char namespacesA[] =
11339 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11340 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11341 "     <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11342 "     <ns1:elem3/>"
11343 "     <ns1:elem4/>"
11344 "     <elem5 xmlns=\"http://blahblah.org\"/>"
11345 "     <ns1:elem6>true</ns1:elem6>"
11346 "   </ns1:elem1>";
11347
11348 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11349 static const char xsd_schema1_xml[] =
11350 "<?xml version='1.0'?>"
11351 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11352 "            targetNamespace='x-schema:test1.xsd'>"
11353 "   <element name='root'>"
11354 "       <complexType>"
11355 "           <sequence maxOccurs='unbounded'>"
11356 "               <any/>"
11357 "           </sequence>"
11358 "       </complexType>"
11359 "   </element>"
11360 "</schema>";
11361
11362 static void test_get_namespaces(void)
11363 {
11364     IXMLDOMSchemaCollection *collection, *collection2;
11365     IXMLDOMDocument2 *doc, *doc2;
11366     IEnumVARIANT *enumv;
11367     IXMLDOMNode *node;
11368     VARIANT_BOOL b;
11369     HRESULT hr;
11370     VARIANT v;
11371     LONG len;
11372     BSTR s;
11373
11374     doc = create_document(&IID_IXMLDOMDocument2);
11375     if (!doc) return;
11376
11377     /* null pointer */
11378     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11379     EXPECT_HR(hr, E_POINTER);
11380
11381     /* no document loaded */
11382     collection = (void*)0xdeadbeef;
11383     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11384     EXPECT_HR(hr, S_OK);
11385     if (hr != S_OK)
11386     {
11387         IXMLDOMDocument_Release(doc);
11388         return;
11389     }
11390     EXPECT_REF(collection, 2);
11391
11392     collection2 = (void*)0xdeadbeef;
11393     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11394     EXPECT_HR(hr, S_OK);
11395     ok(collection == collection2, "got %p\n", collection2);
11396     EXPECT_REF(collection, 3);
11397     IXMLDOMSchemaCollection_Release(collection);
11398
11399     len = -1;
11400     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11401     EXPECT_HR(hr, S_OK);
11402     ok(len == 0, "got %d\n", len);
11403     IXMLDOMSchemaCollection_Release(collection);
11404
11405     /* now with document */
11406     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11407     EXPECT_HR(hr, S_OK);
11408
11409     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11410     EXPECT_HR(hr, S_OK);
11411
11412     len = -1;
11413     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11414     EXPECT_HR(hr, S_OK);
11415     ok(len == 2, "got %d\n", len);
11416
11417     /* try to lookup some uris */
11418     node = (void*)0xdeadbeef;
11419     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11420     EXPECT_HR(hr, S_OK);
11421     ok(node == NULL, "got %p\n", node);
11422
11423     node = (void*)0xdeadbeef;
11424     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11425     EXPECT_HR(hr, S_OK);
11426     ok(node == NULL, "got %p\n", node);
11427
11428     /* load schema and try to add it */
11429     doc2 = create_document(&IID_IXMLDOMDocument2);
11430     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11431     EXPECT_HR(hr, S_OK);
11432
11433     V_VT(&v) = VT_DISPATCH;
11434     V_DISPATCH(&v) = (IDispatch*)doc2;
11435     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11436     EXPECT_HR(hr, E_FAIL);
11437
11438     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11439     EXPECT_HR(hr, S_OK);
11440     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11441     SysFreeString(s);
11442
11443     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11444     EXPECT_HR(hr, S_OK);
11445     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11446     SysFreeString(s);
11447
11448     s = (void*)0xdeadbeef;
11449     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11450     EXPECT_HR(hr, E_FAIL);
11451     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11452
11453     /* enumerate */
11454     enumv = (void*)0xdeadbeef;
11455     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11456 todo_wine
11457     EXPECT_HR(hr, S_OK);
11458     if (hr == S_OK)
11459     {
11460         ok(enumv != NULL, "got %p\n", enumv);
11461
11462         V_VT(&v) = VT_EMPTY;
11463         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11464         EXPECT_HR(hr, S_OK);
11465         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11466         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11467         VariantClear(&v);
11468
11469         V_VT(&v) = VT_EMPTY;
11470         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11471         EXPECT_HR(hr, S_OK);
11472         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11473         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11474         VariantClear(&v);
11475
11476         V_VT(&v) = VT_NULL;
11477         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11478         EXPECT_HR(hr, S_FALSE);
11479         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11480
11481         IEnumVARIANT_Release(enumv);
11482     }
11483     IXMLDOMSchemaCollection_Release(collection);
11484
11485     IXMLDOMDocument2_Release(doc);
11486
11487     /* now with CLSID_DOMDocument60 */
11488     doc = create_document_version(60, &IID_IXMLDOMDocument2);
11489     if (!doc) return;
11490
11491     /* null pointer */
11492     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11493     EXPECT_HR(hr, E_POINTER);
11494
11495     /* no document loaded */
11496     collection = (void*)0xdeadbeef;
11497     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11498     EXPECT_HR(hr, S_OK);
11499     if (hr != S_OK)
11500     {
11501         IXMLDOMDocument_Release(doc);
11502         return;
11503     }
11504     EXPECT_REF(collection, 2);
11505
11506     collection2 = (void*)0xdeadbeef;
11507     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11508     EXPECT_HR(hr, S_OK);
11509     ok(collection == collection2, "got %p\n", collection2);
11510     EXPECT_REF(collection, 3);
11511     IXMLDOMSchemaCollection_Release(collection);
11512
11513     len = -1;
11514     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11515     EXPECT_HR(hr, S_OK);
11516     ok(len == 0, "got %d\n", len);
11517     IXMLDOMSchemaCollection_Release(collection);
11518
11519     /* now with document */
11520     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11521     EXPECT_HR(hr, S_OK);
11522
11523     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11524     EXPECT_HR(hr, S_OK);
11525
11526     len = -1;
11527     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11528     EXPECT_HR(hr, S_OK);
11529     ok(len == 2, "got %d\n", len);
11530
11531     /* try to lookup some uris */
11532     node = (void*)0xdeadbeef;
11533     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11534     EXPECT_HR(hr, E_NOTIMPL);
11535     ok(node == (void*)0xdeadbeef, "got %p\n", node);
11536
11537     /* load schema and try to add it */
11538     doc2 = create_document(&IID_IXMLDOMDocument2);
11539     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11540     EXPECT_HR(hr, S_OK);
11541
11542     V_VT(&v) = VT_DISPATCH;
11543     V_DISPATCH(&v) = (IDispatch*)doc2;
11544     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11545     EXPECT_HR(hr, E_FAIL);
11546     IXMLDOMSchemaCollection_Release(doc2);
11547
11548     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11549     EXPECT_HR(hr, S_OK);
11550     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11551     SysFreeString(s);
11552
11553     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11554     EXPECT_HR(hr, S_OK);
11555     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11556     SysFreeString(s);
11557
11558     s = (void*)0xdeadbeef;
11559     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11560     EXPECT_HR(hr, E_FAIL);
11561     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11562
11563     /* enumerate */
11564     enumv = (void*)0xdeadbeef;
11565     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11566 todo_wine
11567     EXPECT_HR(hr, S_OK);
11568     if (hr == S_OK)
11569     {
11570         ok(enumv != NULL, "got %p\n", enumv);
11571
11572         V_VT(&v) = VT_EMPTY;
11573         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11574         EXPECT_HR(hr, S_OK);
11575         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11576         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11577         VariantClear(&v);
11578
11579         V_VT(&v) = VT_EMPTY;
11580         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11581         EXPECT_HR(hr, S_OK);
11582         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11583         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11584         VariantClear(&v);
11585
11586         V_VT(&v) = VT_NULL;
11587         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11588         EXPECT_HR(hr, S_FALSE);
11589         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11590
11591         IEnumVARIANT_Release(enumv);
11592     }
11593     IXMLDOMSchemaCollection_Release(collection);
11594     IXMLDOMDocument2_Release(doc);
11595     free_bstrs();
11596 }
11597
11598 START_TEST(domdoc)
11599 {
11600     IXMLDOMDocument *doc;
11601     IUnknown *unk;
11602     HRESULT hr;
11603
11604     hr = CoInitialize( NULL );
11605     ok( hr == S_OK, "failed to init com\n");
11606     if (hr != S_OK) return;
11607
11608     test_XMLHTTP();
11609
11610     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
11611     if (hr != S_OK)
11612     {
11613         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
11614         return;
11615     }
11616
11617     IXMLDOMDocument_Release(doc);
11618
11619     test_domdoc();
11620     test_persiststreaminit();
11621     test_domnode();
11622     test_refs();
11623     test_create();
11624     test_getElementsByTagName();
11625     test_get_text();
11626     test_get_childNodes();
11627     test_get_firstChild();
11628     test_get_lastChild();
11629     test_removeChild();
11630     test_replaceChild();
11631     test_removeNamedItem();
11632     test_IXMLDOMDocument2();
11633     test_whitespace();
11634     test_XPath();
11635     test_XSLPattern();
11636     test_cloneNode();
11637     test_xmlTypes();
11638     test_save();
11639     test_testTransforms();
11640     test_namespaces();
11641     test_FormattingXML();
11642     test_nodeTypedValue();
11643     test_TransformWithLoadingLocalFile();
11644     test_put_nodeValue();
11645     test_document_IObjectSafety();
11646     test_splitText();
11647     test_getQualifiedItem();
11648     test_removeQualifiedItem();
11649     test_get_ownerDocument();
11650     test_setAttributeNode();
11651     test_put_dataType();
11652     test_createNode();
11653     test_get_prefix();
11654     test_default_properties();
11655     test_selectSingleNode();
11656     test_events();
11657     test_createProcessingInstruction();
11658     test_put_nodeTypedValue();
11659     test_get_xml();
11660     test_insertBefore();
11661     test_appendChild();
11662     test_get_doctype();
11663     test_get_tagName();
11664     test_get_dataType();
11665     test_get_nodeTypeString();
11666     test_get_attributes();
11667     test_selection();
11668     test_load();
11669     test_dispex();
11670     test_parseerror();
11671     test_getAttributeNode();
11672     test_supporterrorinfo();
11673     test_nodeValue();
11674     test_get_namespaces();
11675
11676     test_xsltemplate();
11677
11678     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11679         &IID_IMXNamespaceManager, (void**)&unk);
11680     if (hr == S_OK)
11681     {
11682         test_mxnamespacemanager();
11683         test_mxnamespacemanager_override();
11684
11685         IUnknown_Release(unk);
11686     }
11687     else
11688         win_skip("MXNamespaceManager is not available\n");
11689
11690     CoUninitialize();
11691 }