mshtml: Keep reference in node returned from get_node.
[wine] / dlls / msxml3 / tests / domdoc.c
1 /*
2  * XML test
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2007-2008 Alistair Leslie-Hughes
6  * Copyright 2010-2011 Adam Martinson for CodeWeavers
7  * Copyright 2010-2012 Nikolay Sivov for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24
25 #define COBJMACROS
26 #define CONST_VTABLE
27
28 #include <stdio.h>
29 #include <assert.h>
30
31 #include "windows.h"
32
33 #include "msxml2.h"
34 #include "msxml2did.h"
35 #include "ole2.h"
36 #include "dispex.h"
37
38 #include "initguid.h"
39 #include "objsafe.h"
40 #include "mshtml.h"
41
42 #include "wine/test.h"
43
44 /* undef the #define in msxml2 so that we can access all versions */
45 #undef CLSID_DOMDocument
46
47 DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
48 DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
49 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
50
51 #define DEFINE_EXPECT(func) \
52     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
53
54 #define SET_EXPECT(func) \
55     expect_ ## func = TRUE
56
57 #define CHECK_EXPECT2(func) \
58     do { \
59         ok(expect_ ##func, "unexpected call " #func "\n"); \
60         called_ ## func = TRUE; \
61     }while(0)
62
63 #define CHECK_CALLED(func) \
64     do { \
65         ok(called_ ## func, "expected " #func "\n"); \
66         expect_ ## func = called_ ## func = FALSE; \
67     }while(0)
68
69 static const char *debugstr_guid(REFIID riid)
70 {
71     static char buf[50];
72
73     if(!riid)
74         return "(null)";
75
76     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
77             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
78             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
79             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
80
81     return buf;
82 }
83
84 static int g_unexpectedcall, g_expectedcall;
85
86 typedef struct
87 {
88     IDispatch IDispatch_iface;
89     LONG ref;
90 } dispevent;
91
92 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
93 {
94     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
95 }
96
97 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
98 {
99     *ppvObject = NULL;
100
101     if ( IsEqualGUID( riid, &IID_IDispatch) ||
102          IsEqualGUID( riid, &IID_IUnknown) )
103     {
104         *ppvObject = iface;
105     }
106     else
107         return E_NOINTERFACE;
108
109     IDispatch_AddRef( iface );
110
111     return S_OK;
112 }
113
114 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
115 {
116     dispevent *This = impl_from_IDispatch( iface );
117     return InterlockedIncrement( &This->ref );
118 }
119
120 static ULONG WINAPI dispevent_Release(IDispatch *iface)
121 {
122     dispevent *This = impl_from_IDispatch( iface );
123     ULONG ref = InterlockedDecrement( &This->ref );
124
125     if (ref == 0)
126         HeapFree(GetProcessHeap(), 0, This);
127
128     return ref;
129 }
130
131 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
132 {
133     g_unexpectedcall++;
134     *pctinfo = 0;
135     return S_OK;
136 }
137
138 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
139         LCID lcid, ITypeInfo **ppTInfo)
140 {
141     g_unexpectedcall++;
142     return S_OK;
143 }
144
145 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
146         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
147 {
148     g_unexpectedcall++;
149     return S_OK;
150 }
151
152 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
153         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
154         EXCEPINFO *excepInfo, UINT *argErr)
155 {
156     ok(member == 0, "expected 0 member, got %d\n", member);
157     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
158     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
159
160     ok(params->cArgs == 0, "got %d\n", params->cArgs);
161     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
162     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
163     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
164
165     ok(result == NULL, "got %p\n", result);
166     ok(excepInfo == NULL, "got %p\n", excepInfo);
167     ok(argErr == NULL, "got %p\n", argErr);
168
169     g_expectedcall++;
170     return E_FAIL;
171 }
172
173 static const IDispatchVtbl dispeventVtbl =
174 {
175     dispevent_QueryInterface,
176     dispevent_AddRef,
177     dispevent_Release,
178     dispevent_GetTypeInfoCount,
179     dispevent_GetTypeInfo,
180     dispevent_GetIDsOfNames,
181     dispevent_Invoke
182 };
183
184 static IDispatch* create_dispevent(void)
185 {
186     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
187
188     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
189     event->ref = 1;
190
191     return (IDispatch*)&event->IDispatch_iface;
192 }
193
194 /* object site */
195 DEFINE_EXPECT(site_qi_IServiceProvider);
196 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
197 DEFINE_EXPECT(site_qi_IOleClientSite);
198
199 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
200 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
201 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
202 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
203 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
204
205 DEFINE_EXPECT(htmldoc2_get_all);
206 DEFINE_EXPECT(htmldoc2_get_url);
207 DEFINE_EXPECT(collection_get_length);
208
209 typedef struct
210 {
211     IServiceProvider IServiceProvider_iface;
212 } testprov_t;
213
214 testprov_t testprov;
215
216 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
217 {
218     *ppvObject = NULL;
219
220     if (IsEqualGUID(riid, &IID_IServiceProvider))
221         CHECK_EXPECT2(site_qi_IServiceProvider);
222
223     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
224         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
225
226     if (IsEqualGUID(riid, &IID_IOleClientSite))
227         CHECK_EXPECT2(site_qi_IOleClientSite);
228
229     if (IsEqualGUID(riid, &IID_IUnknown))
230          *ppvObject = iface;
231     else if (IsEqualGUID(riid, &IID_IServiceProvider))
232          *ppvObject = &testprov.IServiceProvider_iface;
233
234     if (*ppvObject) IUnknown_AddRef(iface);
235
236     return *ppvObject ? S_OK : E_NOINTERFACE;
237 }
238
239 static ULONG WINAPI site_AddRef(IUnknown *iface)
240 {
241     return 2;
242 }
243
244 static ULONG WINAPI site_Release(IUnknown *iface)
245 {
246     return 1;
247 }
248
249 static const IUnknownVtbl testsiteVtbl =
250 {
251     site_QueryInterface,
252     site_AddRef,
253     site_Release
254 };
255
256 typedef struct
257 {
258     IUnknown IUnknown_iface;
259 } testsite_t;
260
261 static testsite_t testsite = { { &testsiteVtbl } };
262
263 /* test IHTMLElementCollection */
264 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
265 {
266     ok(0, "unexpected call\n");
267     *ppvObject = NULL;
268     return E_NOINTERFACE;
269 }
270
271 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
272 {
273     return 2;
274 }
275
276 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
277 {
278     return 1;
279 }
280
281 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
282 {
283     ok(0, "unexpected call\n");
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
288                                                 LCID lcid, ITypeInfo **ppTInfo)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
295                                                 LPOLESTR *rgszNames, UINT cNames,
296                                                 LCID lcid, DISPID *rgDispId)
297 {
298     ok(0, "unexpected call\n");
299     return E_NOTIMPL;
300 }
301
302 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
303                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
304                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
305 {
306     ok(0, "unexpected call\n");
307     return E_NOTIMPL;
308 }
309
310 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
311 {
312     ok(0, "unexpected call\n");
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
317 {
318     ok(0, "unexpected call\n");
319     return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
323 {
324     CHECK_EXPECT2(collection_get_length);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
329 {
330     ok(0, "unexpected call\n");
331     return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
335 {
336     ok(0, "unexpected call\n");
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
341 {
342     ok(0, "unexpected call\n");
343     return E_NOTIMPL;
344 }
345
346 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
347     htmlecoll_QueryInterface,
348     htmlecoll_AddRef,
349     htmlecoll_Release,
350     htmlecoll_GetTypeInfoCount,
351     htmlecoll_GetTypeInfo,
352     htmlecoll_GetIDsOfNames,
353     htmlecoll_Invoke,
354
355     htmlecoll_toString,
356     htmlecoll_put_length,
357     htmlecoll_get_length,
358     htmlecoll_get__newEnum,
359     htmlecoll_item,
360     htmlecoll_tags
361 };
362
363 typedef struct
364 {
365     IHTMLElementCollection IHTMLElementCollection_iface;
366 } testhtmlecoll_t;
367
368 static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
369
370 /* test IHTMLDocument2 */
371 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
372 {
373    trace("\n");
374    *ppvObject = NULL;
375    return E_NOINTERFACE;
376 }
377
378 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
379 {
380     return 2;
381 }
382
383 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
384 {
385     return 1;
386 }
387
388 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
389 {
390     ok(0, "unexpected call\n");
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
395                                                 LCID lcid, ITypeInfo **ppTInfo)
396 {
397     ok(0, "unexpected call\n");
398     return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
402                                                 LPOLESTR *rgszNames, UINT cNames,
403                                                 LCID lcid, DISPID *rgDispId)
404 {
405     ok(0, "unexpected call\n");
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
410                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
411                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
412 {
413     ok(0, "unexpected call\n");
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
418 {
419     ok(0, "unexpected call\n");
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
424 {
425     CHECK_EXPECT2(htmldoc2_get_all);
426     *p = &htmlecoll.IHTMLElementCollection_iface;
427     return S_OK;
428 }
429
430 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
431 {
432     ok(0, "unexpected call\n");
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
437 {
438     ok(0, "unexpected call\n");
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
443 {
444     ok(0, "unexpected call\n");
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
449 {
450     ok(0, "unexpected call\n");
451     return E_NOTIMPL;
452 }
453
454 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
455 {
456     ok(0, "unexpected call\n");
457     return E_NOTIMPL;
458 }
459
460 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
461 {
462     ok(0, "unexpected call\n");
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
467 {
468     ok(0, "unexpected call\n");
469     return E_NOTIMPL;
470 }
471
472 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
473 {
474     ok(0, "unexpected call\n");
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
479 {
480     ok(0, "unexpected call\n");
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
485 {
486     ok(0, "unexpected call\n");
487     return E_NOTIMPL;
488 }
489
490 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
491 {
492     ok(0, "unexpected call\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
497 {
498     ok(0, "unexpected call\n");
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
503 {
504     ok(0, "unexpected call\n");
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
509 {
510     ok(0, "unexpected call\n");
511     return E_NOTIMPL;
512 }
513
514 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
515 {
516     ok(0, "unexpected call\n");
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
521 {
522     ok(0, "unexpected call\n");
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
527 {
528     ok(0, "unexpected call\n");
529     return E_NOTIMPL;
530 }
531
532 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
533 {
534     ok(0, "unexpected call\n");
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
539 {
540     ok(0, "unexpected call\n");
541     return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
545 {
546     ok(0, "unexpected call\n");
547     return E_NOTIMPL;
548 }
549
550 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
551 {
552     ok(0, "unexpected call\n");
553     return E_NOTIMPL;
554 }
555
556 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
557 {
558     ok(0, "unexpected call\n");
559     return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
563 {
564     ok(0, "unexpected call\n");
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
569 {
570     ok(0, "unexpected call\n");
571     return E_NOTIMPL;
572 }
573
574 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
575 {
576     ok(0, "unexpected call\n");
577     return E_NOTIMPL;
578 }
579
580 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
581 {
582     ok(0, "unexpected call\n");
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
587 {
588     ok(0, "unexpected call\n");
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
593 {
594     ok(0, "unexpected call\n");
595     return E_NOTIMPL;
596 }
597
598 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
599 {
600     ok(0, "unexpected call\n");
601     return E_NOTIMPL;
602 }
603
604 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
605 {
606     ok(0, "unexpected call\n");
607     return E_NOTIMPL;
608 }
609
610 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
611 {
612     ok(0, "unexpected call\n");
613     return E_NOTIMPL;
614 }
615
616 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
617 {
618     CHECK_EXPECT2(htmldoc2_get_url);
619     *p = SysAllocString(NULL);
620     return S_OK;
621 }
622
623 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
624 {
625     ok(0, "unexpected call\n");
626     return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
630 {
631     ok(0, "unexpected call\n");
632     return E_NOTIMPL;
633 }
634
635 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
636 {
637     ok(0, "unexpected call\n");
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
642 {
643     ok(0, "unexpected call\n");
644     return E_NOTIMPL;
645 }
646
647 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
648 {
649     ok(0, "unexpected call\n");
650     return E_NOTIMPL;
651 }
652
653 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
654 {
655     ok(0, "unexpected call\n");
656     return E_NOTIMPL;
657 }
658
659 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
660 {
661     ok(0, "unexpected call\n");
662     return E_NOTIMPL;
663 }
664
665 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
666 {
667     ok(0, "unexpected call\n");
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
672 {
673     ok(0, "unexpected call\n");
674     return E_NOTIMPL;
675 }
676
677 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
678 {
679     ok(0, "unexpected call\n");
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
684 {
685     ok(0, "unexpected call\n");
686     return E_NOTIMPL;
687 }
688
689 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
690 {
691     ok(0, "unexpected call\n");
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
696 {
697     ok(0, "unexpected call\n");
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
708 {
709     ok(0, "unexpected call\n");
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
714 {
715     ok(0, "unexpected call\n");
716     return E_NOTIMPL;
717 }
718
719 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
720 {
721     ok(0, "unexpected call\n");
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
726 {
727     ok(0, "unexpected call\n");
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
732 {
733     ok(0, "unexpected call\n");
734     return E_NOTIMPL;
735 }
736
737 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
738 {
739     ok(0, "unexpected call\n");
740     return E_NOTIMPL;
741 }
742
743 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
744                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
745 {
746     ok(0, "unexpected call\n");
747     return E_NOTIMPL;
748 }
749
750 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
751 {
752     ok(0, "unexpected call\n");
753     return E_NOTIMPL;
754 }
755
756 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
757 {
758     ok(0, "unexpected call\n");
759     return E_NOTIMPL;
760 }
761
762 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
763                                                         VARIANT_BOOL *pfRet)
764 {
765     ok(0, "unexpected call\n");
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
770                                                         VARIANT_BOOL *pfRet)
771 {
772     ok(0, "unexpected call\n");
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
777                                                         VARIANT_BOOL *pfRet)
778 {
779     ok(0, "unexpected call\n");
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
784                                                         VARIANT_BOOL *pfRet)
785 {
786     ok(0, "unexpected call\n");
787     return E_NOTIMPL;
788 }
789
790 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
791                                                         BSTR *pfRet)
792 {
793     ok(0, "unexpected call\n");
794     return E_NOTIMPL;
795 }
796
797 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
798                                                         VARIANT *pfRet)
799 {
800     ok(0, "unexpected call\n");
801     return E_NOTIMPL;
802 }
803
804 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
805                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
806 {
807     ok(0, "unexpected call\n");
808     return E_NOTIMPL;
809 }
810
811 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
812                                                         VARIANT_BOOL *pfRet)
813 {
814     ok(0, "unexpected call\n");
815     return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
819                                                  IHTMLElement **newElem)
820 {
821     ok(0, "unexpected call\n");
822     return E_NOTIMPL;
823 }
824
825 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
826 {
827     ok(0, "unexpected call\n");
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
832 {
833     ok(0, "unexpected call\n");
834     return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
838 {
839     ok(0, "unexpected call\n");
840     return E_NOTIMPL;
841 }
842
843 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
844 {
845     ok(0, "unexpected call\n");
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
850 {
851     ok(0, "unexpected call\n");
852     return E_NOTIMPL;
853 }
854
855 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
856 {
857     ok(0, "unexpected call\n");
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
862 {
863     ok(0, "unexpected call\n");
864     return E_NOTIMPL;
865 }
866
867 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
868 {
869     ok(0, "unexpected call\n");
870     return E_NOTIMPL;
871 }
872
873 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
874 {
875     ok(0, "unexpected call\n");
876     return E_NOTIMPL;
877 }
878
879 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
880 {
881     ok(0, "unexpected call\n");
882     return E_NOTIMPL;
883 }
884
885 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
886 {
887     ok(0, "unexpected call\n");
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
892 {
893     ok(0, "unexpected call\n");
894     return E_NOTIMPL;
895 }
896
897 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
898 {
899     ok(0, "unexpected call\n");
900     return E_NOTIMPL;
901 }
902
903 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
904 {
905     ok(0, "unexpected call\n");
906     return E_NOTIMPL;
907 }
908
909 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
910 {
911     ok(0, "unexpected call\n");
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
916 {
917     ok(0, "unexpected call\n");
918     return E_NOTIMPL;
919 }
920
921 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
922 {
923     ok(0, "unexpected call\n");
924     return E_NOTIMPL;
925 }
926
927 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
928 {
929     ok(0, "unexpected call\n");
930     return E_NOTIMPL;
931 }
932
933 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
934 {
935     ok(0, "unexpected call\n");
936     return E_NOTIMPL;
937 }
938
939 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
940 {
941     ok(0, "unexpected call\n");
942     return E_NOTIMPL;
943 }
944
945 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
946 {
947     ok(0, "unexpected call\n");
948     return E_NOTIMPL;
949 }
950
951 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
952 {
953     ok(0, "unexpected call\n");
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
958 {
959     ok(0, "unexpected call\n");
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
964 {
965     ok(0, "unexpected call\n");
966     return E_NOTIMPL;
967 }
968
969 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
970 {
971     ok(0, "unexpected call\n");
972     return E_NOTIMPL;
973 }
974
975 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
976 {
977     ok(0, "unexpected call\n");
978     return E_NOTIMPL;
979 }
980
981 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
982 {
983     ok(0, "unexpected call\n");
984     return E_NOTIMPL;
985 }
986
987 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
988 {
989     ok(0, "unexpected call\n");
990     return E_NOTIMPL;
991 }
992
993 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
994 {
995     ok(0, "unexpected call\n");
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
1000 {
1001     ok(0, "unexpected call\n");
1002     return E_NOTIMPL;
1003 }
1004
1005 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1006 {
1007     ok(0, "unexpected call\n");
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1012 {
1013     ok(0, "unexpected call\n");
1014     return E_NOTIMPL;
1015 }
1016
1017 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1018 {
1019     ok(0, "unexpected call\n");
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1024 {
1025     ok(0, "unexpected call\n");
1026     return E_NOTIMPL;
1027 }
1028
1029 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1030                                                         IHTMLElement **elementHit)
1031 {
1032     ok(0, "unexpected call\n");
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1037 {
1038     ok(0, "unexpected call\n");
1039     return E_NOTIMPL;
1040 }
1041
1042 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
1043                                                    IHTMLStyleSheetsCollection **p)
1044 {
1045     ok(0, "unexpected call\n");
1046     return E_NOTIMPL;
1047 }
1048
1049 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1050 {
1051     ok(0, "unexpected call\n");
1052     return E_NOTIMPL;
1053 }
1054
1055 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1056 {
1057     ok(0, "unexpected call\n");
1058     return E_NOTIMPL;
1059 }
1060
1061 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1062 {
1063     ok(0, "unexpected call\n");
1064     return E_NOTIMPL;
1065 }
1066
1067 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1068 {
1069     ok(0, "unexpected call\n");
1070     return E_NOTIMPL;
1071 }
1072
1073 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
1074 {
1075     ok(0, "unexpected call\n");
1076     return E_NOTIMPL;
1077 }
1078
1079 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1080                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1081 {
1082     ok(0, "unexpected call\n");
1083     return E_NOTIMPL;
1084 }
1085
1086 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
1087     htmldoc2_QueryInterface,
1088     htmldoc2_AddRef,
1089     htmldoc2_Release,
1090     htmldoc2_GetTypeInfoCount,
1091     htmldoc2_GetTypeInfo,
1092     htmldoc2_GetIDsOfNames,
1093     htmldoc2_Invoke,
1094     htmldoc2_get_Script,
1095     htmldoc2_get_all,
1096     htmldoc2_get_body,
1097     htmldoc2_get_activeElement,
1098     htmldoc2_get_images,
1099     htmldoc2_get_applets,
1100     htmldoc2_get_links,
1101     htmldoc2_get_forms,
1102     htmldoc2_get_anchors,
1103     htmldoc2_put_title,
1104     htmldoc2_get_title,
1105     htmldoc2_get_scripts,
1106     htmldoc2_put_designMode,
1107     htmldoc2_get_designMode,
1108     htmldoc2_get_selection,
1109     htmldoc2_get_readyState,
1110     htmldoc2_get_frames,
1111     htmldoc2_get_embeds,
1112     htmldoc2_get_plugins,
1113     htmldoc2_put_alinkColor,
1114     htmldoc2_get_alinkColor,
1115     htmldoc2_put_bgColor,
1116     htmldoc2_get_bgColor,
1117     htmldoc2_put_fgColor,
1118     htmldoc2_get_fgColor,
1119     htmldoc2_put_linkColor,
1120     htmldoc2_get_linkColor,
1121     htmldoc2_put_vlinkColor,
1122     htmldoc2_get_vlinkColor,
1123     htmldoc2_get_referrer,
1124     htmldoc2_get_location,
1125     htmldoc2_get_lastModified,
1126     htmldoc2_put_URL,
1127     htmldoc2_get_URL,
1128     htmldoc2_put_domain,
1129     htmldoc2_get_domain,
1130     htmldoc2_put_cookie,
1131     htmldoc2_get_cookie,
1132     htmldoc2_put_expando,
1133     htmldoc2_get_expando,
1134     htmldoc2_put_charset,
1135     htmldoc2_get_charset,
1136     htmldoc2_put_defaultCharset,
1137     htmldoc2_get_defaultCharset,
1138     htmldoc2_get_mimeType,
1139     htmldoc2_get_fileSize,
1140     htmldoc2_get_fileCreatedDate,
1141     htmldoc2_get_fileModifiedDate,
1142     htmldoc2_get_fileUpdatedDate,
1143     htmldoc2_get_security,
1144     htmldoc2_get_protocol,
1145     htmldoc2_get_nameProp,
1146     htmldoc2_write,
1147     htmldoc2_writeln,
1148     htmldoc2_open,
1149     htmldoc2_close,
1150     htmldoc2_clear,
1151     htmldoc2_queryCommandSupported,
1152     htmldoc2_queryCommandEnabled,
1153     htmldoc2_queryCommandState,
1154     htmldoc2_queryCommandIndeterm,
1155     htmldoc2_queryCommandText,
1156     htmldoc2_queryCommandValue,
1157     htmldoc2_execCommand,
1158     htmldoc2_execCommandShowHelp,
1159     htmldoc2_createElement,
1160     htmldoc2_put_onhelp,
1161     htmldoc2_get_onhelp,
1162     htmldoc2_put_onclick,
1163     htmldoc2_get_onclick,
1164     htmldoc2_put_ondblclick,
1165     htmldoc2_get_ondblclick,
1166     htmldoc2_put_onkeyup,
1167     htmldoc2_get_onkeyup,
1168     htmldoc2_put_onkeydown,
1169     htmldoc2_get_onkeydown,
1170     htmldoc2_put_onkeypress,
1171     htmldoc2_get_onkeypress,
1172     htmldoc2_put_onmouseup,
1173     htmldoc2_get_onmouseup,
1174     htmldoc2_put_onmousedown,
1175     htmldoc2_get_onmousedown,
1176     htmldoc2_put_onmousemove,
1177     htmldoc2_get_onmousemove,
1178     htmldoc2_put_onmouseout,
1179     htmldoc2_get_onmouseout,
1180     htmldoc2_put_onmouseover,
1181     htmldoc2_get_onmouseover,
1182     htmldoc2_put_onreadystatechange,
1183     htmldoc2_get_onreadystatechange,
1184     htmldoc2_put_onafterupdate,
1185     htmldoc2_get_onafterupdate,
1186     htmldoc2_put_onrowexit,
1187     htmldoc2_get_onrowexit,
1188     htmldoc2_put_onrowenter,
1189     htmldoc2_get_onrowenter,
1190     htmldoc2_put_ondragstart,
1191     htmldoc2_get_ondragstart,
1192     htmldoc2_put_onselectstart,
1193     htmldoc2_get_onselectstart,
1194     htmldoc2_elementFromPoint,
1195     htmldoc2_get_parentWindow,
1196     htmldoc2_get_styleSheets,
1197     htmldoc2_put_onbeforeupdate,
1198     htmldoc2_get_onbeforeupdate,
1199     htmldoc2_put_onerrorupdate,
1200     htmldoc2_get_onerrorupdate,
1201     htmldoc2_toString,
1202     htmldoc2_createStyleSheet
1203 };
1204
1205 typedef struct
1206 {
1207     IHTMLDocument2 IHTMLDocument2_iface;
1208 } testhtmldoc2_t;
1209
1210 static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
1211
1212 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1213 {
1214     *ppvObject = NULL;
1215
1216     if (IsEqualGUID(riid, &IID_IUnknown) ||
1217         IsEqualGUID(riid, &IID_IServiceProvider))
1218     {
1219         *ppvObject = iface;
1220         IServiceProvider_AddRef(iface);
1221         return S_OK;
1222     }
1223
1224     ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
1225
1226     return E_NOINTERFACE;
1227 }
1228
1229 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1230 {
1231     return 2;
1232 }
1233
1234 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1235 {
1236     return 1;
1237 }
1238
1239 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1240 {
1241     *obj = NULL;
1242
1243     if (IsEqualGUID(service, &SID_SBindHost) &&
1244         IsEqualGUID(riid, &IID_IBindHost))
1245     {
1246         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1247     }
1248     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1249              IsEqualGUID(riid, &IID_IHTMLDocument2))
1250     {
1251         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1252     }
1253     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1254              IsEqualGUID(riid, &IID_IHTMLDocument2))
1255     {
1256         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1257         *obj = &htmldoc2.IHTMLDocument2_iface;
1258         return S_OK;
1259     }
1260     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1261              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1262     {
1263         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1264     }
1265     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1266              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1267     {
1268         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1269     }
1270     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1271              IsEqualGUID(riid, &IID_IStream))
1272     {
1273         /* FIXME: unidentified service id */
1274     }
1275     else
1276         ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
1277
1278     return E_NOTIMPL;
1279 }
1280
1281 static const IServiceProviderVtbl testprovVtbl =
1282 {
1283     sp_QueryInterface,
1284     sp_AddRef,
1285     sp_Release,
1286     sp_QueryService
1287 };
1288
1289 testprov_t testprov = { { &testprovVtbl } };
1290
1291 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1292 static void _expect_children(IXMLDOMNode *node, int line)
1293 {
1294     VARIANT_BOOL b;
1295     HRESULT hr;
1296
1297     b = VARIANT_FALSE;
1298     hr = IXMLDOMNode_hasChildNodes(node, &b);
1299     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1300     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1301 }
1302
1303 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1304 static void _expect_no_children(IXMLDOMNode *node, int line)
1305 {
1306     VARIANT_BOOL b;
1307     HRESULT hr;
1308
1309     b = VARIANT_TRUE;
1310     hr = IXMLDOMNode_hasChildNodes(node, &b);
1311     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1312     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1313 }
1314
1315 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1316 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1317 {
1318     ULONG rc = IUnknown_AddRef(obj);
1319     IUnknown_Release(obj);
1320     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1321 }
1322
1323 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1324 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1325 {
1326     LONG length;
1327     HRESULT hr;
1328
1329     length = 0;
1330     hr = IXMLDOMNodeList_get_length(list, &length);
1331     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1332     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1333 }
1334
1335 #define EXPECT_HR(hr,hr_exp) \
1336     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1337
1338 static const WCHAR szEmpty[] = { 0 };
1339 static const WCHAR szIncomplete[] = {
1340     '<','?','x','m','l',' ',
1341     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1342 };
1343 static const WCHAR szComplete1[] = {
1344     '<','?','x','m','l',' ',
1345     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1346     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1347 };
1348 static const WCHAR szComplete2[] = {
1349     '<','?','x','m','l',' ',
1350     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1351     '<','o','>','<','/','o','>','\n',0
1352 };
1353 static const WCHAR szComplete3[] = {
1354     '<','?','x','m','l',' ',
1355     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1356     '<','a','>','<','/','a','>','\n',0
1357 };
1358 static const char complete4A[] =
1359     "<?xml version=\'1.0\'?>\n"
1360     "<lc dl=\'str1\'>\n"
1361         "<bs vr=\'str2\' sz=\'1234\'>"
1362             "fn1.txt\n"
1363         "</bs>\n"
1364         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1365             "fn2.txt\n"
1366         "</pr>\n"
1367         "<empty></empty>\n"
1368         "<fo>\n"
1369             "<ba>\n"
1370                 "f1\n"
1371             "</ba>\n"
1372         "</fo>\n"
1373     "</lc>\n";
1374
1375 static const WCHAR szComplete5[] = {
1376     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1377     'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
1378     ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
1379         '<','S',':','s','c','o','p','e','>',
1380             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1381         '<','/','S',':','s','c','o','p','e','>',
1382         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1383             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1384             'c','o','m','p','u','t','e','r',
1385         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1386     '<','/','S',':','s','e','a','r','c','h','>',0
1387 };
1388
1389 static const WCHAR szComplete6[] = {
1390     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1391     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1392     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1393 };
1394
1395 static const CHAR szNonUnicodeXML[] =
1396 "<?xml version='1.0' encoding='Windows-1252'?>\n"
1397 "<open></open>\n";
1398
1399 static const char szExampleXML[] =
1400 "<?xml version='1.0' encoding='utf-8'?>\n"
1401 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1402 "    <elem>\n"
1403 "        <a>A1 field</a>\n"
1404 "        <b>B1 field</b>\n"
1405 "        <c>C1 field</c>\n"
1406 "        <d>D1 field</d>\n"
1407 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1408 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1409 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1410 "            </html>\n"
1411 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1412 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1413 "            </html>\n"
1414 "        </description>\n"
1415 "    </elem>\n"
1416 "\n"
1417 "    <elem>\n"
1418 "        <a>A2 field</a>\n"
1419 "        <b>B2 field</b>\n"
1420 "        <c type=\"old\">C2 field</c>\n"
1421 "        <d>D2 field</d>\n"
1422 "    </elem>\n"
1423 "\n"
1424 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1425 "        <a>A3 field</a>\n"
1426 "        <b>B3 field</b>\n"
1427 "        <c>C3 field</c>\n"
1428 "    </elem>\n"
1429 "\n"
1430 "    <elem>\n"
1431 "        <a>A4 field</a>\n"
1432 "        <b>B4 field</b>\n"
1433 "        <foo:c>C4 field</foo:c>\n"
1434 "        <d>D4 field</d>\n"
1435 "    </elem>\n"
1436 "</root>\n";
1437
1438 static const CHAR szNodeTypesXML[] =
1439 "<?xml version='1.0'?>"
1440 "<!-- comment node 0 -->"
1441 "<root id='0' depth='0'>"
1442 "   <!-- comment node 1 -->"
1443 "   text node 0"
1444 "   <x id='1' depth='1'>"
1445 "       <?foo value='PI for x'?>"
1446 "       <!-- comment node 2 -->"
1447 "       text node 1"
1448 "       <a id='3' depth='2'/>"
1449 "       <b id='4' depth='2'/>"
1450 "       <c id='5' depth='2'/>"
1451 "   </x>"
1452 "   <y id='2' depth='1'>"
1453 "       <?bar value='PI for y'?>"
1454 "       <!-- comment node 3 -->"
1455 "       text node 2"
1456 "       <a id='6' depth='2'/>"
1457 "       <b id='7' depth='2'/>"
1458 "       <c id='8' depth='2'/>"
1459 "   </y>"
1460 "</root>";
1461
1462 static const CHAR szTransformXML[] =
1463 "<?xml version=\"1.0\"?>\n"
1464 "<greeting>\n"
1465 "Hello World\n"
1466 "</greeting>";
1467
1468 static  const CHAR szTransformSSXML[] =
1469 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1470 "   <xsl:output method=\"html\"/>\n"
1471 "   <xsl:template match=\"/\">\n"
1472 "       <xsl:apply-templates select=\"greeting\"/>\n"
1473 "   </xsl:template>\n"
1474 "   <xsl:template match=\"greeting\">\n"
1475 "       <html>\n"
1476 "           <body>\n"
1477 "               <h1>\n"
1478 "                   <xsl:value-of select=\".\"/>\n"
1479 "               </h1>\n"
1480 "           </body>\n"
1481 "       </html>\n"
1482 "   </xsl:template>\n"
1483 "</xsl:stylesheet>";
1484
1485 static  const CHAR szTransformOutput[] =
1486 "<html><body><h1>"
1487 "Hello World"
1488 "</h1></body></html>";
1489
1490 static const CHAR szTypeValueXML[] =
1491 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1492 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1493 "   <string>Wine</string>\n"
1494 "   <string2 dt:dt=\"string\">String</string2>\n"
1495 "   <number dt:dt=\"number\">12.44</number>\n"
1496 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1497 "   <int dt:dt=\"int\">-13</int>\n"
1498 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1499 "   <bool dt:dt=\"boolean\">1</bool>\n"
1500 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1501 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1502 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1503 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1504 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1505 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1506 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1507 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1508 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1509 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1510 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1511 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1512 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1513 "   <float dt:dt=\"float\">41221.421</float>\n"
1514 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1515 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1516 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1517 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1518 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1519 "</root>";
1520
1521 static const CHAR szBasicTransformSSXMLPart1[] =
1522 "<?xml version=\"1.0\"?>"
1523 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1524 "<xsl:output method=\"html\"/>\n"
1525 "<xsl:template match=\"/\">"
1526 "<HTML><BODY><TABLE>"
1527 "        <xsl:apply-templates select='document(\"";
1528
1529 static const CHAR szBasicTransformSSXMLPart2[] =
1530 "\")/bottle/wine'>"
1531 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1532 "        </xsl:apply-templates>"
1533 "</TABLE></BODY></HTML>"
1534 "</xsl:template>"
1535 "<xsl:template match=\"bottle\">"
1536 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1537 "</xsl:template>"
1538 "<xsl:template match=\"name\">"
1539 "   <TD><xsl:apply-templates /></TD>"
1540 "</xsl:template>"
1541 "<xsl:template match=\"cost\">"
1542 "   <TD><xsl:apply-templates /></TD>"
1543 "</xsl:template>"
1544 "</xsl:stylesheet>";
1545
1546 static const CHAR szBasicTransformXML[] =
1547 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1548
1549 static const CHAR szBasicTransformOutput[] =
1550 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1551
1552 #define SZ_EMAIL_DTD \
1553 "<!DOCTYPE email ["\
1554 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1555 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1556 "       <!ATTLIST email sent (yes|no) \"no\">"\
1557 "   <!ELEMENT recipients    (to+,cc*)>"\
1558 "   <!ELEMENT to            (#PCDATA)>"\
1559 "       <!ATTLIST to name CDATA #IMPLIED>"\
1560 "   <!ELEMENT cc            (#PCDATA)>"\
1561 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1562 "   <!ELEMENT from          (#PCDATA)>"\
1563 "       <!ATTLIST from name CDATA #IMPLIED>"\
1564 "   <!ELEMENT reply-to      (#PCDATA)>"\
1565 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1566 "   <!ELEMENT subject       ANY>"\
1567 "   <!ELEMENT body          ANY>"\
1568 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1569 "   <!ELEMENT attachment    (#PCDATA)>"\
1570 "       <!ATTLIST attachment id ID #REQUIRED>"\
1571 "]>"
1572
1573 static const CHAR szEmailXML[] =
1574 "<?xml version=\"1.0\"?>"
1575 SZ_EMAIL_DTD
1576 "<email attachments=\"patch1\">"
1577 "   <recipients>"
1578 "       <to>wine-patches@winehq.org</to>"
1579 "   </recipients>"
1580 "   <from name=\"Anonymous\">user@localhost</from>"
1581 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1582 "   <body>"
1583 "       It no longer causes spontaneous combustion..."
1584 "   </body>"
1585 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1586 "</email>";
1587
1588 static const CHAR szEmailXML_0D[] =
1589 "<?xml version=\"1.0\"?>"
1590 SZ_EMAIL_DTD
1591 "<email attachments=\"patch1\">"
1592 "   <recipients>"
1593 "       <to>wine-patches@winehq.org</to>"
1594 "   </recipients>"
1595 "   <from name=\"Anonymous\">user@localhost</from>"
1596 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
1597 "   <body>"
1598 "       <undecl />"
1599 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1600 "   </body>"
1601 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1602 "</email>";
1603
1604 static const CHAR szEmailXML_0E[] =
1605 "<?xml version=\"1.0\"?>"
1606 SZ_EMAIL_DTD
1607 "<email attachments=\"patch1\">"
1608 "   <recipients>"
1609 "       <to>wine-patches@winehq.org</to>"
1610 "   </recipients>"
1611 "   <from name=\"Anonymous\">user@localhost</from>"
1612 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1613 "   <body>"
1614 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1615 "   </body>"
1616 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1617 "</email>";
1618
1619 static const CHAR szEmailXML_11[] =
1620 "<?xml version=\"1.0\"?>"
1621 SZ_EMAIL_DTD
1622 "<email attachments=\"patch1\">"
1623 "   <recipients>"
1624 "   </recipients>"
1625 "   <from name=\"Anonymous\">user@localhost</from>"
1626 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1627 "   <body>"
1628 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1629 "   </body>"
1630 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1631 "</email>";
1632
1633 static const CHAR szEmailXML_13[] =
1634 "<?xml version=\"1.0\"?>"
1635 SZ_EMAIL_DTD
1636 "<msg attachments=\"patch1\">"
1637 "   <recipients>"
1638 "       <to>wine-patches@winehq.org</to>"
1639 "   </recipients>"
1640 "   <from name=\"Anonymous\">user@localhost</from>"
1641 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1642 "   <body>"
1643 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1644 "   </body>"
1645 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1646 "</msg>";
1647
1648 static const CHAR szEmailXML_14[] =
1649 "<?xml version=\"1.0\"?>"
1650 SZ_EMAIL_DTD
1651 "<email attachments=\"patch1\">"
1652 "   <to>wine-patches@winehq.org</to>"
1653 "   <from name=\"Anonymous\">user@localhost</from>"
1654 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1655 "   <body>"
1656 "       XML_INVALID_CONTENT 0xC00CE014"
1657 "   </body>"
1658 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1659 "</email>";
1660
1661 static const CHAR szEmailXML_15[] =
1662 "<?xml version=\"1.0\"?>"
1663 SZ_EMAIL_DTD
1664 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1665 "   <recipients>"
1666 "       <to>wine-patches@winehq.org</to>"
1667 "   </recipients>"
1668 "   <from name=\"Anonymous\">user@localhost</from>"
1669 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1670 "   <body>"
1671 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1672 "   </body>"
1673 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1674 "</email>";
1675
1676 static const CHAR szEmailXML_16[] =
1677 "<?xml version=\"1.0\"?>"
1678 SZ_EMAIL_DTD
1679 "<email attachments=\"patch1\">"
1680 "   <recipients>"
1681 "       <to>wine-patches@winehq.org</to>"
1682 "   </recipients>"
1683 "   <from name=\"Anonymous\">user@localhost</from>"
1684 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1685 "   <body enc=\"ASCII\">"
1686 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1687 "   </body>"
1688 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1689 "</email>";
1690
1691 static const CHAR szEmailXML_17[] =
1692 "<?xml version=\"1.0\"?>"
1693 SZ_EMAIL_DTD
1694 "<email attachments=\"patch1\" sent=\"true\">"
1695 "   <recipients>"
1696 "       <to>wine-patches@winehq.org</to>"
1697 "   </recipients>"
1698 "   <from name=\"Anonymous\">user@localhost</from>"
1699 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1700 "   <body>"
1701 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1702 "   </body>"
1703 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1704 "</email>";
1705
1706 static const CHAR szEmailXML_18[] =
1707 "<?xml version=\"1.0\"?>"
1708 SZ_EMAIL_DTD
1709 "<email attachments=\"patch1\">"
1710 "   oops"
1711 "   <recipients>"
1712 "       <to>wine-patches@winehq.org</to>"
1713 "   </recipients>"
1714 "   <from name=\"Anonymous\">user@localhost</from>"
1715 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1716 "   <body>"
1717 "       XML_ILLEGAL_TEXT 0xC00CE018"
1718 "   </body>"
1719 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1720 "</email>";
1721
1722 static const CHAR szEmailXML_20[] =
1723 "<?xml version=\"1.0\"?>"
1724 SZ_EMAIL_DTD
1725 "<email>"
1726 "   <recipients>"
1727 "       <to>wine-patches@winehq.org</to>"
1728 "   </recipients>"
1729 "   <from name=\"Anonymous\">user@localhost</from>"
1730 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1731 "   <body>"
1732 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1733 "   </body>"
1734 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1735 "</email>";
1736
1737 static const char xpath_simple_list[] =
1738 "<?xml version=\"1.0\"?>"
1739 "<root>"
1740 "   <a attr1=\"1\" attr2=\"2\" />"
1741 "   <b/>"
1742 "   <c/>"
1743 "   <d/>"
1744 "</root>";
1745
1746 static const char default_ns_doc[] = {
1747     "<?xml version=\"1.0\"?>"
1748     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1749     "    d=\"d attr\" />"
1750 };
1751
1752 static const WCHAR nonexistent_fileW[] = {
1753     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1754 };
1755 static const WCHAR nonexistent_attrW[] = {
1756     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1757 };
1758 static const WCHAR szDocument[] = {
1759     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1760 };
1761
1762 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1763 static WCHAR szdl[] = { 'd','l',0 };
1764 static const WCHAR szvr[] = { 'v','r',0 };
1765 static const WCHAR szlc[] = { 'l','c',0 };
1766 static WCHAR szbs[] = { 'b','s',0 };
1767 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1768 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1769 static const WCHAR szstar[] = { '*',0 };
1770 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1771
1772 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1773 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1774 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1775
1776 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1777 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1778 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1779 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1780                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1781 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1782                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1783
1784 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1785 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1786
1787 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1788                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1789 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1790                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1791                              '!',']',']','>',0};
1792 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1793 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1794
1795 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1796 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1797 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1798
1799 #define expect_bstr_eq_and_free(bstr, expect) { \
1800     BSTR bstrExp = alloc_str_from_narrow(expect); \
1801     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1802     SysFreeString(bstr); \
1803     SysFreeString(bstrExp); \
1804 }
1805
1806 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1807
1808 #define ole_check(expr) { \
1809     HRESULT r = expr; \
1810     ok(r == S_OK, #expr " returned %x\n", r); \
1811 }
1812
1813 #define ole_expect(expr, expect) { \
1814     HRESULT r = expr; \
1815     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1816 }
1817
1818 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1819
1820 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1821 {
1822     void *obj = NULL;
1823     HRESULT hr;
1824
1825     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1826     if (hr != S_OK)
1827         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1828
1829     return obj;
1830 }
1831
1832 #define _create(cls) cls, #cls
1833
1834 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1835 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1836 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1837 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1838 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1839
1840 static BSTR alloc_str_from_narrow(const char *str)
1841 {
1842     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1843     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1844     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1845     return ret;
1846 }
1847
1848 static BSTR alloced_bstrs[256];
1849 static int alloced_bstrs_count;
1850
1851 static BSTR _bstr_(const char *str)
1852 {
1853     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1854     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1855     return alloced_bstrs[alloced_bstrs_count++];
1856 }
1857
1858 static void free_bstrs(void)
1859 {
1860     int i;
1861     for (i = 0; i < alloced_bstrs_count; i++)
1862         SysFreeString(alloced_bstrs[i]);
1863     alloced_bstrs_count = 0;
1864 }
1865
1866 static VARIANT _variantbstr_(const char *str)
1867 {
1868     VARIANT v;
1869     V_VT(&v) = VT_BSTR;
1870     V_BSTR(&v) = _bstr_(str);
1871     return v;
1872 }
1873
1874 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1875 {
1876     for (;;)
1877     {
1878         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1879         while (*sRight == '\r' || *sRight == '\n') sRight++;
1880         if (*sLeft != *sRight) return FALSE;
1881         if (!*sLeft) return TRUE;
1882         sLeft++;
1883         sRight++;
1884     }
1885 }
1886
1887 static void get_str_for_type(DOMNodeType type, char *buf)
1888 {
1889     switch (type)
1890     {
1891         case NODE_ATTRIBUTE:
1892             strcpy(buf, "A");
1893             break;
1894         case NODE_ELEMENT:
1895             strcpy(buf, "E");
1896             break;
1897         case NODE_DOCUMENT:
1898             strcpy(buf, "D");
1899             break;
1900         case NODE_TEXT:
1901             strcpy(buf, "T");
1902             break;
1903         case NODE_COMMENT:
1904             strcpy(buf, "C");
1905             break;
1906         case NODE_PROCESSING_INSTRUCTION:
1907             strcpy(buf, "P");
1908             break;
1909         default:
1910             wsprintfA(buf, "[%d]", type);
1911     }
1912 }
1913
1914 static int get_node_position(IXMLDOMNode *node)
1915 {
1916     HRESULT r;
1917     int pos = 0;
1918
1919     IXMLDOMNode_AddRef(node);
1920     do
1921     {
1922         IXMLDOMNode *new_node;
1923
1924         pos++;
1925         r = IXMLDOMNode_get_previousSibling(node, &new_node);
1926         ok(SUCCEEDED(r), "get_previousSibling failed\n");
1927         IXMLDOMNode_Release(node);
1928         node = new_node;
1929     } while (r == S_OK);
1930     return pos;
1931 }
1932
1933 static void node_to_string(IXMLDOMNode *node, char *buf)
1934 {
1935     HRESULT r = S_OK;
1936     DOMNodeType type;
1937
1938     if (node == NULL)
1939     {
1940         lstrcpyA(buf, "(null)");
1941         return;
1942     }
1943
1944     IXMLDOMNode_AddRef(node);
1945     while (r == S_OK)
1946     {
1947         IXMLDOMNode *new_node;
1948
1949         ole_check(IXMLDOMNode_get_nodeType(node, &type));
1950         get_str_for_type(type, buf);
1951         buf+=strlen(buf);
1952
1953         if (type == NODE_ATTRIBUTE)
1954         {
1955             BSTR bstr;
1956             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1957             *(buf++) = '\'';
1958             wsprintfA(buf, "%ws", bstr);
1959             buf += strlen(buf);
1960             *(buf++) = '\'';
1961             SysFreeString(bstr);
1962
1963             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1964         }
1965         else
1966         {
1967             r = IXMLDOMNode_get_parentNode(node, &new_node);
1968             wsprintf(buf, "%d", get_node_position(node));
1969             buf += strlen(buf);
1970         }
1971
1972         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1973         IXMLDOMNode_Release(node);
1974         node = new_node;
1975         if (r == S_OK)
1976             *(buf++) = '.';
1977     }
1978
1979     *buf = 0;
1980 }
1981
1982 static char *list_to_string(IXMLDOMNodeList *list)
1983 {
1984     static char buf[4096];
1985     char *pos = buf;
1986     LONG len = 0;
1987     int i;
1988
1989     if (list == NULL)
1990     {
1991         lstrcpyA(buf, "(null)");
1992         return buf;
1993     }
1994     ole_check(IXMLDOMNodeList_get_length(list, &len));
1995     for (i = 0; i < len; i++)
1996     {
1997         IXMLDOMNode *node;
1998         if (i > 0)
1999             *(pos++) = ' ';
2000         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2001         node_to_string(node, pos);
2002         pos += strlen(pos);
2003         IXMLDOMNode_Release(node);
2004     }
2005     *pos = 0;
2006     return buf;
2007 }
2008
2009 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
2010 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
2011
2012 struct docload_ret_t {
2013     VARIANT_BOOL b;
2014     HRESULT hr;
2015 };
2016
2017 struct leading_spaces_t {
2018     const CLSID *clsid;
2019     const char *name;
2020     struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
2021 };
2022
2023 static const struct leading_spaces_t leading_spaces_classdata[] = {
2024     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2025     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2026     { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2027     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2028     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2029     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2030     { NULL }
2031 };
2032
2033 static const char* leading_spaces_xmldata[] = {
2034     "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
2035     " <?xml version=\"1.0\"?><root/>",
2036     "\n<?xml version=\"1.0\"?><root/>",
2037     "\t<?xml version=\"1.0\"?><root/>",
2038     "\r\n<?xml version=\"1.0\"?><root/>",
2039     "\r<?xml version=\"1.0\"?><root/>",
2040     "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
2041     0
2042 };
2043
2044 static void test_domdoc( void )
2045 {
2046     HRESULT r, hr;
2047     IXMLDOMDocument *doc;
2048     IXMLDOMParseError *error;
2049     IXMLDOMElement *element = NULL;
2050     IXMLDOMNode *node;
2051     IXMLDOMText *nodetext = NULL;
2052     IXMLDOMComment *node_comment = NULL;
2053     IXMLDOMAttribute *node_attr = NULL;
2054     IXMLDOMNode *nodeChild = NULL;
2055     IXMLDOMProcessingInstruction *nodePI = NULL;
2056     const struct leading_spaces_t *class_ptr;
2057     const char **data_ptr;
2058     VARIANT_BOOL b;
2059     VARIANT var;
2060     BSTR str;
2061     LONG code, ref;
2062     LONG nLength = 0;
2063     WCHAR buff[100];
2064     char path[MAX_PATH];
2065     int index;
2066
2067     GetTempPathA(MAX_PATH, path);
2068     strcat(path, "leading_spaces.xml");
2069
2070     /* Load document with leading spaces
2071      *
2072      * Test all CLSIDs with all test data XML strings
2073      */
2074     class_ptr = leading_spaces_classdata;
2075     index = 0;
2076     while (class_ptr->clsid)
2077     {
2078         HRESULT hr;
2079         int i;
2080
2081         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
2082              &IID_IXMLDOMDocument, (void**)&doc);
2083         if (hr != S_OK) {
2084             win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
2085             class_ptr++;
2086             index++;
2087             continue;
2088         }
2089
2090         data_ptr = leading_spaces_xmldata;
2091         i = 0;
2092         while (*data_ptr) {
2093             BSTR data = _bstr_(*data_ptr);
2094             DWORD written;
2095             HANDLE file;
2096
2097             file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2098             ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
2099
2100             WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
2101             CloseHandle(file);
2102
2103             b = 0xc;
2104             V_VT(&var) = VT_BSTR;
2105             V_BSTR(&var) = _bstr_(path);
2106             hr = IXMLDOMDocument_load(doc, var, &b);
2107         todo_wine {
2108             EXPECT_HR(hr, class_ptr->ret[0].hr);
2109             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
2110         }
2111             DeleteFileA(path);
2112
2113             b = 0xc;
2114             hr = IXMLDOMDocument_loadXML(doc, data, &b);
2115             EXPECT_HR(hr, class_ptr->ret[1].hr);
2116             ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
2117
2118             data_ptr++;
2119             i++;
2120         }
2121
2122         class_ptr++;
2123         index++;
2124         free_bstrs();
2125     }
2126
2127     doc = create_document(&IID_IXMLDOMDocument);
2128     if (!doc) return;
2129
2130 if (0)
2131 {
2132     /* crashes on native */
2133     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2134 }
2135
2136     /* try some stupid things */
2137     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2138     EXPECT_HR(hr, S_FALSE);
2139
2140     b = VARIANT_TRUE;
2141     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2142     EXPECT_HR(hr, S_FALSE);
2143     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2144
2145     /* try to load a document from a nonexistent file */
2146     b = VARIANT_TRUE;
2147     str = SysAllocString( nonexistent_fileW );
2148     VariantInit(&var);
2149     V_VT(&var) = VT_BSTR;
2150     V_BSTR(&var) = str;
2151
2152     r = IXMLDOMDocument_load( doc, var, &b);
2153     ok( r == S_FALSE, "loadXML succeeded\n");
2154     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2155     SysFreeString( str );
2156
2157     /* try load an empty document */
2158     b = VARIANT_TRUE;
2159     str = SysAllocString( szEmpty );
2160     r = IXMLDOMDocument_loadXML( doc, str, &b );
2161     ok( r == S_FALSE, "loadXML succeeded\n");
2162     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2163     SysFreeString( str );
2164
2165     r = IXMLDOMDocument_get_async( doc, &b );
2166     ok( r == S_OK, "get_async failed (%08x)\n", r);
2167     ok( b == VARIANT_TRUE, "Wrong default value\n");
2168
2169     /* check that there's no document element */
2170     element = NULL;
2171     r = IXMLDOMDocument_get_documentElement( doc, &element );
2172     ok( r == S_FALSE, "should be no document element\n");
2173
2174     /* try finding a node */
2175     node = NULL;
2176     str = SysAllocString( szstr1 );
2177     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2178     ok( r == S_FALSE, "ret %08x\n", r );
2179     SysFreeString( str );
2180
2181     b = VARIANT_TRUE;
2182     str = SysAllocString( szIncomplete );
2183     r = IXMLDOMDocument_loadXML( doc, str, &b );
2184     ok( r == S_FALSE, "loadXML succeeded\n");
2185     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2186     SysFreeString( str );
2187
2188     /* check that there's no document element */
2189     element = (IXMLDOMElement*)1;
2190     r = IXMLDOMDocument_get_documentElement( doc, &element );
2191     ok( r == S_FALSE, "should be no document element\n");
2192     ok( element == NULL, "Element should be NULL\n");
2193
2194     /* test for BSTR handling, pass broken BSTR */
2195     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2196     /* just a big length */
2197     *(DWORD*)buff = 0xf0f0;
2198     b = VARIANT_FALSE;
2199     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2200     ok( r == S_OK, "loadXML failed\n");
2201     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2202
2203     /* loadXML ignores the encoding attribute and always expects Unicode */
2204     b = VARIANT_FALSE;
2205     str = SysAllocString( szComplete6 );
2206     r = IXMLDOMDocument_loadXML( doc, str, &b );
2207     ok( r == S_OK, "loadXML failed\n");
2208     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2209     SysFreeString( str );
2210
2211     /* try a BSTR containing a Windows-1252 document */
2212     b = VARIANT_TRUE;
2213     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
2214     r = IXMLDOMDocument_loadXML( doc, str, &b );
2215     ok( r == S_FALSE, "loadXML succeeded\n");
2216     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2217     SysFreeString( str );
2218
2219     /* try to load something valid */
2220     b = VARIANT_FALSE;
2221     str = SysAllocString( szComplete1 );
2222     r = IXMLDOMDocument_loadXML( doc, str, &b );
2223     ok( r == S_OK, "loadXML failed\n");
2224     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2225     SysFreeString( str );
2226
2227     /* check if nodename is correct */
2228     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2229     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2230
2231     str = (BSTR)0xdeadbeef;
2232     r = IXMLDOMDocument_get_baseName( doc, &str );
2233     ok ( r == S_FALSE, "got 0x%08x\n", r);
2234     ok (str == NULL, "got %p\n", str);
2235
2236     /* content doesn't matter here */
2237     str = NULL;
2238     r = IXMLDOMDocument_get_nodeName( doc, &str );
2239     ok ( r == S_OK, "get_nodeName wrong code\n");
2240     ok ( str != NULL, "str is null\n");
2241     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2242     SysFreeString( str );
2243
2244     /* test put_text */
2245     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2246     ok( r == E_FAIL, "ret %08x\n", r );
2247
2248     /* check that there's a document element */
2249     element = NULL;
2250     r = IXMLDOMDocument_get_documentElement( doc, &element );
2251     ok( r == S_OK, "should be a document element\n");
2252     if( element )
2253     {
2254         IObjectIdentity *ident;
2255
2256         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2257         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2258
2259         IXMLDOMElement_Release( element );
2260         element = NULL;
2261     }
2262
2263     /* as soon as we call loadXML again, the document element will disappear */
2264     b = 2;
2265     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2266     ok( r == S_FALSE, "loadXML failed\n");
2267     ok( b == 2, "variant modified\n");
2268     r = IXMLDOMDocument_get_documentElement( doc, &element );
2269     ok( r == S_FALSE, "should be no document element\n");
2270
2271     /* try to load something else simple and valid */
2272     b = VARIANT_FALSE;
2273     str = SysAllocString( szComplete3 );
2274     r = IXMLDOMDocument_loadXML( doc, str, &b );
2275     ok( r == S_OK, "loadXML failed\n");
2276     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2277     SysFreeString( str );
2278
2279     /* try something a little more complicated */
2280     b = FALSE;
2281     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2282     ok( r == S_OK, "loadXML failed\n");
2283     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2284
2285     r = IXMLDOMDocument_get_parseError( doc, &error );
2286     ok( r == S_OK, "returns %08x\n", r );
2287
2288     r = IXMLDOMParseError_get_errorCode( error, &code );
2289     ok( r == S_FALSE, "returns %08x\n", r );
2290     ok( code == 0, "code %d\n", code );
2291     IXMLDOMParseError_Release( error );
2292
2293     /* test createTextNode */
2294     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2295     ok( r == S_OK, "returns %08x\n", r );
2296     IXMLDOMText_Release(nodetext);
2297
2298     str = SysAllocString( szOpen );
2299     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2300     ok( r == E_INVALIDARG, "returns %08x\n", r );
2301     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2302     ok( r == S_OK, "returns %08x\n", r );
2303     SysFreeString( str );
2304     if(nodetext)
2305     {
2306         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2307         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2308
2309         /* Text Last Child Checks */
2310         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2311         ok(r == E_INVALIDARG, "ret %08x\n", r );
2312
2313         nodeChild = (IXMLDOMNode*)0x1;
2314         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2315         ok(r == S_FALSE, "ret %08x\n", r );
2316         ok(nodeChild == NULL, "nodeChild not NULL\n");
2317
2318         /* test length property */
2319         r = IXMLDOMText_get_length(nodetext, NULL);
2320         ok(r == E_INVALIDARG, "ret %08x\n", r );
2321
2322         r = IXMLDOMText_get_length(nodetext, &nLength);
2323         ok(r == S_OK, "ret %08x\n", r );
2324         ok(nLength == 4, "expected 4 got %d\n", nLength);
2325
2326         /* put data Tests */
2327         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2328         ok(r == S_OK, "ret %08x\n", r );
2329
2330         /* get data Tests */
2331         r = IXMLDOMText_get_data(nodetext, &str);
2332         ok(r == S_OK, "ret %08x\n", r );
2333         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2334         SysFreeString(str);
2335
2336         /* Confirm XML text is good */
2337         r = IXMLDOMText_get_xml(nodetext, &str);
2338         ok(r == S_OK, "ret %08x\n", r );
2339         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2340         SysFreeString(str);
2341
2342         /* Confirm we get the put_data Text back */
2343         r = IXMLDOMText_get_text(nodetext, &str);
2344         ok(r == S_OK, "ret %08x\n", r );
2345         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2346         SysFreeString(str);
2347
2348         /* test substringData */
2349         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2350         ok(r == E_INVALIDARG, "ret %08x\n", r );
2351
2352         /* test substringData - Invalid offset */
2353         str = (BSTR)&szElement;
2354         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2355         ok(r == E_INVALIDARG, "ret %08x\n", r );
2356         ok( str == NULL, "incorrect string\n");
2357
2358         /* test substringData - Invalid offset */
2359         str = (BSTR)&szElement;
2360         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2361         ok(r == S_FALSE, "ret %08x\n", r );
2362         ok( str == NULL, "incorrect string\n");
2363
2364         /* test substringData - Invalid size */
2365         str = (BSTR)&szElement;
2366         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2367         ok(r == E_INVALIDARG, "ret %08x\n", r );
2368         ok( str == NULL, "incorrect string\n");
2369
2370         /* test substringData - Invalid size */
2371         str = (BSTR)&szElement;
2372         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2373         ok(r == S_FALSE, "ret %08x\n", r );
2374         ok( str == NULL, "incorrect string\n");
2375
2376         /* test substringData - Start of string */
2377         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2378         ok(r == S_OK, "ret %08x\n", r );
2379         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2380         SysFreeString(str);
2381
2382         /* test substringData - Middle of string */
2383         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2384         ok(r == S_OK, "ret %08x\n", r );
2385         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2386         SysFreeString(str);
2387
2388         /* test substringData - End of string */
2389         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2390         ok(r == S_OK, "ret %08x\n", r );
2391         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2392         SysFreeString(str);
2393
2394         /* test appendData */
2395         r = IXMLDOMText_appendData(nodetext, NULL);
2396         ok(r == S_OK, "ret %08x\n", r );
2397
2398         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2399         ok(r == S_OK, "ret %08x\n", r );
2400
2401         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2402         ok(r == S_OK, "ret %08x\n", r );
2403
2404         r = IXMLDOMText_get_text(nodetext, &str);
2405         ok(r == S_OK, "ret %08x\n", r );
2406         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2407         SysFreeString(str);
2408
2409         /* test insertData */
2410         str = SysAllocStringLen(NULL, 0);
2411         r = IXMLDOMText_insertData(nodetext, -1, str);
2412         ok(r == S_OK, "ret %08x\n", r );
2413
2414         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2415         ok(r == S_OK, "ret %08x\n", r );
2416
2417         r = IXMLDOMText_insertData(nodetext, 1000, str);
2418         ok(r == S_OK, "ret %08x\n", r );
2419
2420         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2421         ok(r == S_OK, "ret %08x\n", r );
2422
2423         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2424         ok(r == S_OK, "ret %08x\n", r );
2425
2426         r = IXMLDOMText_insertData(nodetext, 0, str);
2427         ok(r == S_OK, "ret %08x\n", r );
2428         SysFreeString(str);
2429
2430         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2431         ok(r == E_INVALIDARG, "ret %08x\n", r );
2432
2433         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2434         ok(r == E_INVALIDARG, "ret %08x\n", r );
2435
2436         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2437         ok(r == S_OK, "ret %08x\n", r );
2438
2439         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2440         ok(r == S_OK, "ret %08x\n", r );
2441
2442         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2443         ok(r == S_OK, "ret %08x\n", r );
2444
2445         r = IXMLDOMText_get_text(nodetext, &str);
2446         ok(r == S_OK, "ret %08x\n", r );
2447         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2448         SysFreeString(str);
2449
2450         /* delete data */
2451         /* invalid arguments */
2452         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2453         ok(r == E_INVALIDARG, "ret %08x\n", r );
2454
2455         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2456         ok(r == S_OK, "ret %08x\n", r );
2457
2458         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2459         ok(r == E_INVALIDARG, "ret %08x\n", r );
2460
2461         r = IXMLDOMText_get_length(nodetext, &nLength);
2462         ok(r == S_OK, "ret %08x\n", r );
2463         ok(nLength == 43, "expected 43 got %d\n", nLength);
2464
2465         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2466         ok(r == S_OK, "ret %08x\n", r );
2467
2468         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2469         ok(r == E_INVALIDARG, "ret %08x\n", r );
2470
2471         /* delete from start */
2472         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2473         ok(r == S_OK, "ret %08x\n", r );
2474
2475         r = IXMLDOMText_get_length(nodetext, &nLength);
2476         ok(r == S_OK, "ret %08x\n", r );
2477         ok(nLength == 38, "expected 38 got %d\n", nLength);
2478
2479         r = IXMLDOMText_get_text(nodetext, &str);
2480         ok(r == S_OK, "ret %08x\n", r );
2481         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2482         SysFreeString(str);
2483
2484         /* delete from end */
2485         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2486         ok(r == S_OK, "ret %08x\n", r );
2487
2488         r = IXMLDOMText_get_length(nodetext, &nLength);
2489         ok(r == S_OK, "ret %08x\n", r );
2490         ok(nLength == 35, "expected 35 got %d\n", nLength);
2491
2492         r = IXMLDOMText_get_text(nodetext, &str);
2493         ok(r == S_OK, "ret %08x\n", r );
2494         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2495         SysFreeString(str);
2496
2497         /* delete from inside */
2498         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2499         ok(r == S_OK, "ret %08x\n", r );
2500
2501         r = IXMLDOMText_get_length(nodetext, &nLength);
2502         ok(r == S_OK, "ret %08x\n", r );
2503         ok(nLength == 2, "expected 2 got %d\n", nLength);
2504
2505         r = IXMLDOMText_get_text(nodetext, &str);
2506         ok(r == S_OK, "ret %08x\n", r );
2507         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2508         SysFreeString(str);
2509
2510         /* delete whole data ... */
2511         r = IXMLDOMText_get_length(nodetext, &nLength);
2512         ok(r == S_OK, "ret %08x\n", r );
2513
2514         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2515         ok(r == S_OK, "ret %08x\n", r );
2516         /* ... and try again with empty string */
2517         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2518         ok(r == S_OK, "ret %08x\n", r );
2519
2520         /* test put_data */
2521         V_VT(&var) = VT_BSTR;
2522         V_BSTR(&var) = SysAllocString(szstr1);
2523         r = IXMLDOMText_put_nodeValue(nodetext, var);
2524         ok(r == S_OK, "ret %08x\n", r );
2525         VariantClear(&var);
2526
2527         r = IXMLDOMText_get_text(nodetext, &str);
2528         ok(r == S_OK, "ret %08x\n", r );
2529         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2530         SysFreeString(str);
2531
2532         /* test put_data */
2533         V_VT(&var) = VT_I4;
2534         V_I4(&var) = 99;
2535         r = IXMLDOMText_put_nodeValue(nodetext, var);
2536         ok(r == S_OK, "ret %08x\n", r );
2537         VariantClear(&var);
2538
2539         r = IXMLDOMText_get_text(nodetext, &str);
2540         ok(r == S_OK, "ret %08x\n", r );
2541         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2542         SysFreeString(str);
2543
2544         /* ::replaceData() */
2545         V_VT(&var) = VT_BSTR;
2546         V_BSTR(&var) = SysAllocString(szstr1);
2547         r = IXMLDOMText_put_nodeValue(nodetext, var);
2548         ok(r == S_OK, "ret %08x\n", r );
2549         VariantClear(&var);
2550
2551         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2552         ok(r == E_INVALIDARG, "ret %08x\n", r );
2553         r = IXMLDOMText_get_text(nodetext, &str);
2554         ok(r == S_OK, "ret %08x\n", r );
2555         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2556         SysFreeString(str);
2557
2558         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2559         ok(r == S_OK, "ret %08x\n", r );
2560         r = IXMLDOMText_get_text(nodetext, &str);
2561         ok(r == S_OK, "ret %08x\n", r );
2562         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2563         SysFreeString(str);
2564
2565         /* NULL pointer means delete */
2566         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2567         ok(r == S_OK, "ret %08x\n", r );
2568         r = IXMLDOMText_get_text(nodetext, &str);
2569         ok(r == S_OK, "ret %08x\n", r );
2570         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2571         SysFreeString(str);
2572
2573         /* empty string means delete */
2574         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2575         ok(r == S_OK, "ret %08x\n", r );
2576         r = IXMLDOMText_get_text(nodetext, &str);
2577         ok(r == S_OK, "ret %08x\n", r );
2578         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2579         SysFreeString(str);
2580
2581         /* zero count means insert */
2582         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2583         ok(r == S_OK, "ret %08x\n", r );
2584         r = IXMLDOMText_get_text(nodetext, &str);
2585         ok(r == S_OK, "ret %08x\n", r );
2586         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2587         SysFreeString(str);
2588
2589         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2590         ok(r == S_OK, "ret %08x\n", r );
2591
2592         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2593         ok(r == S_OK, "ret %08x\n", r );
2594         r = IXMLDOMText_get_text(nodetext, &str);
2595         ok(r == S_OK, "ret %08x\n", r );
2596         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2597         SysFreeString(str);
2598
2599         /* nonempty string, count greater than its length */
2600         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2601         ok(r == S_OK, "ret %08x\n", r );
2602         r = IXMLDOMText_get_text(nodetext, &str);
2603         ok(r == S_OK, "ret %08x\n", r );
2604         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2605         SysFreeString(str);
2606
2607         /* nonempty string, count less than its length */
2608         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2609         ok(r == S_OK, "ret %08x\n", r );
2610         r = IXMLDOMText_get_text(nodetext, &str);
2611         ok(r == S_OK, "ret %08x\n", r );
2612         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2613         SysFreeString(str);
2614
2615         IXMLDOMText_Release( nodetext );
2616     }
2617
2618     /* test Create Comment */
2619     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2620     ok( r == E_INVALIDARG, "returns %08x\n", r );
2621     node_comment = (IXMLDOMComment*)0x1;
2622
2623     /* empty comment */
2624     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2625     ok( r == S_OK, "returns %08x\n", r );
2626     str = (BSTR)0x1;
2627     r = IXMLDOMComment_get_data(node_comment, &str);
2628     ok( r == S_OK, "returns %08x\n", r );
2629     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2630     IXMLDOMComment_Release(node_comment);
2631     SysFreeString(str);
2632
2633     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2634     ok( r == S_OK, "returns %08x\n", r );
2635     str = (BSTR)0x1;
2636     r = IXMLDOMComment_get_data(node_comment, &str);
2637     ok( r == S_OK, "returns %08x\n", r );
2638     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2639     IXMLDOMComment_Release(node_comment);
2640     SysFreeString(str);
2641
2642     str = SysAllocString(szComment);
2643     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2644     SysFreeString(str);
2645     ok( r == S_OK, "returns %08x\n", r );
2646     if(node_comment)
2647     {
2648         /* Last Child Checks */
2649         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2650         ok(r == E_INVALIDARG, "ret %08x\n", r );
2651
2652         nodeChild = (IXMLDOMNode*)0x1;
2653         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2654         ok(r == S_FALSE, "ret %08x\n", r );
2655         ok(nodeChild == NULL, "pLastChild not NULL\n");
2656
2657         /* baseName */
2658         str = (BSTR)0xdeadbeef;
2659         r = IXMLDOMComment_get_baseName(node_comment, &str);
2660         ok(r == S_FALSE, "ret %08x\n", r );
2661         ok(str == NULL, "Expected NULL\n");
2662
2663         IXMLDOMComment_Release( node_comment );
2664     }
2665
2666     /* test Create Attribute */
2667     str = SysAllocString(szAttribute);
2668     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2669     ok( r == E_INVALIDARG, "returns %08x\n", r );
2670     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2671     ok( r == S_OK, "returns %08x\n", r );
2672     IXMLDOMText_Release( node_attr);
2673     SysFreeString(str);
2674
2675     /* test Processing Instruction */
2676     str = SysAllocStringLen(NULL, 0);
2677     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2678     ok( r == E_INVALIDARG, "returns %08x\n", r );
2679     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2680     ok( r == E_FAIL, "returns %08x\n", r );
2681     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2682     ok( r == E_FAIL, "returns %08x\n", r );
2683     SysFreeString(str);
2684
2685     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2686     ok( r == S_OK, "returns %08x\n", r );
2687     if(nodePI)
2688     {
2689         /* Last Child Checks */
2690         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2691         ok(r == E_INVALIDARG, "ret %08x\n", r );
2692
2693         nodeChild = (IXMLDOMNode*)0x1;
2694         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2695         ok(r == S_FALSE, "ret %08x\n", r );
2696         ok(nodeChild == NULL, "nodeChild not NULL\n");
2697
2698         /* test nodeName */
2699         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2700         ok(r == S_OK, "ret %08x\n", r );
2701         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2702         SysFreeString(str);
2703
2704         /* test baseName */
2705         str = (BSTR)0x1;
2706         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2707         ok(r == S_OK, "ret %08x\n", r );
2708         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2709         SysFreeString(str);
2710
2711         /* test Target */
2712         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2713         ok(r == S_OK, "ret %08x\n", r );
2714         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2715         SysFreeString(str);
2716
2717         /* test get_data */
2718         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2719         ok(r == S_OK, "ret %08x\n", r );
2720         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2721         SysFreeString(str);
2722
2723         /* test put_data */
2724         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2725         ok(r == E_FAIL, "ret %08x\n", r );
2726
2727         /* test put_data */
2728         V_VT(&var) = VT_BSTR;
2729         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2730         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2731         ok(r == E_FAIL, "ret %08x\n", r );
2732         VariantClear(&var);
2733
2734         /* test get nodeName */
2735         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2736         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2737         ok(r == S_OK, "ret %08x\n", r );
2738         SysFreeString(str);
2739
2740         IXMLDOMProcessingInstruction_Release(nodePI);
2741     }
2742
2743     ref = IXMLDOMDocument_Release( doc );
2744     ok( ref == 0, "got %d\n", ref);
2745
2746     free_bstrs();
2747 }
2748
2749 static void test_persiststreaminit(void)
2750 {
2751     IXMLDOMDocument *doc;
2752     IPersistStreamInit *streaminit;
2753     HRESULT hr;
2754
2755     doc = create_document(&IID_IXMLDOMDocument);
2756     if (!doc) return;
2757
2758     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2759     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2760
2761     hr = IPersistStreamInit_InitNew(streaminit);
2762     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2763
2764     IXMLDOMDocument_Release(doc);
2765 }
2766
2767 static void test_domnode( void )
2768 {
2769     HRESULT r;
2770     IXMLDOMDocument *doc, *owner = NULL;
2771     IXMLDOMElement *element = NULL;
2772     IXMLDOMNamedNodeMap *map = NULL;
2773     IXMLDOMNode *node = NULL, *next = NULL;
2774     IXMLDOMNodeList *list = NULL;
2775     IXMLDOMAttribute *attr = NULL;
2776     DOMNodeType type = NODE_INVALID;
2777     VARIANT_BOOL b;
2778     BSTR str;
2779     VARIANT var;
2780     LONG count;
2781
2782     doc = create_document(&IID_IXMLDOMDocument);
2783     if (!doc) return;
2784
2785     b = FALSE;
2786     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2787     ok( r == S_OK, "loadXML failed\n");
2788     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2789
2790     EXPECT_CHILDREN(doc);
2791
2792     r = IXMLDOMDocument_get_documentElement( doc, &element );
2793     ok( r == S_OK, "should be a document element\n");
2794     ok( element != NULL, "should be an element\n");
2795
2796     VariantInit(&var);
2797     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2798
2799     r = IXMLDOMNode_get_nodeValue( doc, NULL );
2800     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2801
2802     r = IXMLDOMNode_get_nodeValue( doc, &var );
2803     ok( r == S_FALSE, "nextNode returned wrong code\n");
2804     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2805     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2806
2807     if (element)
2808     {
2809         owner = NULL;
2810         r = IXMLDOMNode_get_ownerDocument( element, &owner );
2811         ok( r == S_OK, "get_ownerDocument return code\n");
2812         ok( owner != doc, "get_ownerDocument return\n");
2813         IXMLDOMDocument_Release(owner);
2814
2815         type = NODE_INVALID;
2816         r = IXMLDOMNode_get_nodeType( element, &type);
2817         ok( r == S_OK, "got %08x\n", r);
2818         ok( type == NODE_ELEMENT, "node not an element\n");
2819
2820         str = NULL;
2821         r = IXMLDOMNode_get_baseName( element, &str );
2822         ok( r == S_OK, "get_baseName returned wrong code\n");
2823         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2824         SysFreeString(str);
2825
2826         /* check if nodename is correct */
2827         r = IXMLDOMElement_get_nodeName( element, NULL );
2828         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2829
2830         /* content doesn't matter here */
2831         str = NULL;
2832         r = IXMLDOMElement_get_nodeName( element, &str );
2833         ok ( r == S_OK, "get_nodeName wrong code\n");
2834         ok ( str != NULL, "str is null\n");
2835         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2836         SysFreeString( str );
2837
2838         str = SysAllocString( nonexistent_fileW );
2839         V_VT(&var) = VT_I4;
2840         V_I4(&var) = 0x1234;
2841         r = IXMLDOMElement_getAttribute( element, str, &var );
2842         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2843         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2844         VariantClear(&var);
2845
2846         str = SysAllocString( szdl );   
2847         V_VT(&var) = VT_I4;
2848         V_I4(&var) = 0x1234;
2849         r = IXMLDOMElement_getAttribute( element, str, &var );
2850         ok( r == S_OK, "getAttribute ret %08x\n", r );
2851         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2852         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2853         VariantClear( &var );
2854
2855         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2856         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2857
2858         r = IXMLDOMElement_getAttribute( element, str, NULL );
2859         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2860
2861         attr = NULL;
2862         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2863         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2864         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2865         if (attr)
2866         {
2867             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2868             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2869
2870             /* attribute doesn't have a parent in msxml interpretation */
2871             node = (IXMLDOMNode*)0xdeadbeef;
2872             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2873             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2874             ok( node == NULL, "Expected NULL, got %p\n", node );
2875
2876             IXMLDOMAttribute_Release(attr);
2877         }
2878
2879         SysFreeString( str );
2880
2881         r = IXMLDOMElement_get_attributes( element, &map );
2882         ok( r == S_OK, "get_attributes returned wrong code\n");
2883         ok( map != NULL, "should be attributes\n");
2884
2885         EXPECT_CHILDREN(element);
2886     }
2887     else
2888         ok( FALSE, "no element\n");
2889
2890     if (map)
2891     {
2892         str = SysAllocString( szdl );
2893         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2894         ok( r == S_OK, "getNamedItem returned wrong code\n");
2895         ok( node != NULL, "should be attributes\n");
2896         IXMLDOMNode_Release(node);
2897         SysFreeString( str );
2898
2899         str = SysAllocString( szdl );
2900         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2901         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2902         SysFreeString( str );
2903
2904         /* something that isn't in complete4A */
2905         str = SysAllocString( szOpen );
2906         node = (IXMLDOMNode *) 1;
2907         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2908         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2909         ok( node == NULL, "getNamedItem should have returned NULL\n");
2910         SysFreeString( str );
2911
2912         /* test indexed access of attributes */
2913         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2914         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2915
2916         r = IXMLDOMNamedNodeMap_get_length( map, &count );
2917         ok ( r == S_OK, "get_length wrong code\n");
2918         ok ( count == 1, "get_length != 1\n");
2919
2920         node = NULL;
2921         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2922         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2923         ok ( node == NULL, "there is no node\n");
2924
2925         node = NULL;
2926         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2927         ok ( r == S_FALSE, "get_item (1) wrong code\n");
2928         ok ( node == NULL, "there is no attribute\n");
2929
2930         node = NULL;
2931         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2932         ok ( r == S_OK, "get_item (0) wrong code\n");
2933         ok ( node != NULL, "should be attribute\n");
2934
2935         r = IXMLDOMNode_get_nodeName( node, NULL );
2936         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2937
2938         /* content doesn't matter here */
2939         str = NULL;
2940         r = IXMLDOMNode_get_nodeName( node, &str );
2941         ok ( r == S_OK, "get_nodeName wrong code\n");
2942         ok ( str != NULL, "str is null\n");
2943         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2944         SysFreeString( str );
2945         IXMLDOMNode_Release( node );
2946
2947         /* test sequential access of attributes */
2948         node = NULL;
2949         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2950         ok ( r == S_OK, "nextNode (first time) wrong code\n");
2951         ok ( node != NULL, "nextNode, should be attribute\n");
2952         IXMLDOMNode_Release( node );
2953
2954         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2955         ok ( r != S_OK, "nextNode (second time) wrong code\n");
2956         ok ( node == NULL, "nextNode, there is no attribute\n");
2957
2958         r = IXMLDOMNamedNodeMap_reset( map );
2959         ok ( r == S_OK, "reset should return S_OK\n");
2960
2961         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2962         ok ( r == S_OK, "nextNode (third time) wrong code\n");
2963         ok ( node != NULL, "nextNode, should be attribute\n");
2964     }
2965     else
2966         ok( FALSE, "no map\n");
2967
2968     if (node)
2969     {
2970         type = NODE_INVALID;
2971         r = IXMLDOMNode_get_nodeType( node, &type);
2972         ok( r == S_OK, "getNamedItem returned wrong code\n");
2973         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2974
2975         str = NULL;
2976         r = IXMLDOMNode_get_baseName( node, NULL );
2977         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2978
2979         str = NULL;
2980         r = IXMLDOMNode_get_baseName( node, &str );
2981         ok( r == S_OK, "get_baseName returned wrong code\n");
2982         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2983         SysFreeString( str );
2984
2985         r = IXMLDOMNode_get_childNodes( node, NULL );
2986         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2987
2988         r = IXMLDOMNode_get_childNodes( node, &list );
2989         ok( r == S_OK, "get_childNodes returned wrong code\n");
2990
2991         if (list)
2992         {
2993             r = IXMLDOMNodeList_nextNode( list, &next );
2994             ok( r == S_OK, "nextNode returned wrong code\n");
2995         }
2996         else
2997             ok( FALSE, "no childlist\n");
2998
2999         if (next)
3000         {
3001             EXPECT_NO_CHILDREN(next);
3002
3003             type = NODE_INVALID;
3004             r = IXMLDOMNode_get_nodeType( next, &type);
3005             ok( r == S_OK, "getNamedItem returned wrong code\n");
3006             ok( type == NODE_TEXT, "node not text\n");
3007
3008             str = (BSTR) 1;
3009             r = IXMLDOMNode_get_baseName( next, &str );
3010             ok( r == S_FALSE, "get_baseName returned wrong code\n");
3011             ok( str == NULL, "basename was wrong\n");
3012             SysFreeString(str);
3013         }
3014         else
3015             ok( FALSE, "no next\n");
3016
3017         if (next)
3018             IXMLDOMNode_Release( next );
3019         next = NULL;
3020         if (list)
3021             IXMLDOMNodeList_Release( list );
3022         list = NULL;
3023         if (node)
3024             IXMLDOMNode_Release( node );
3025     }
3026     else
3027         ok( FALSE, "no node\n");
3028     node = NULL;
3029
3030     if (map)
3031         IXMLDOMNamedNodeMap_Release( map );
3032
3033     /* now traverse the tree from the root element */
3034     if (element)
3035     {
3036         r = IXMLDOMNode_get_childNodes( element, &list );
3037         ok( r == S_OK, "get_childNodes returned wrong code\n");
3038
3039         /* using get_item for child list doesn't advance the position */
3040         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3041         expect_node(node, "E2.E2.D1");
3042         IXMLDOMNode_Release(node);
3043         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3044         expect_node(node, "E1.E2.D1");
3045         IXMLDOMNode_Release(node);
3046         ole_check(IXMLDOMNodeList_reset(list));
3047
3048         IXMLDOMNodeList_AddRef(list);
3049         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3050         ole_check(IXMLDOMNodeList_reset(list));
3051
3052         node = (void*)0xdeadbeef;
3053         str = SysAllocString(szdl);
3054         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3055         SysFreeString(str);
3056         ok( r == S_FALSE, "ret %08x\n", r );
3057         ok( node == NULL, "node %p\n", node );
3058
3059         str = SysAllocString(szbs);
3060         r = IXMLDOMNode_selectSingleNode( element, str, &node );
3061         SysFreeString(str);
3062         ok( r == S_OK, "ret %08x\n", r );
3063         r = IXMLDOMNode_Release( node );
3064         ok( r == 0, "ret %08x\n", r );
3065     }
3066     else
3067         ok( FALSE, "no element\n");
3068
3069     if (list)
3070     {
3071         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3072         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3073
3074         r = IXMLDOMNodeList_get_length(list, NULL);
3075         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3076
3077         r = IXMLDOMNodeList_get_length( list, &count );
3078         ok( r == S_OK, "get_length returns %08x\n", r );
3079         ok( count == 4, "get_length got %d\n", count );
3080
3081         r = IXMLDOMNodeList_nextNode(list, NULL);
3082         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3083
3084         r = IXMLDOMNodeList_nextNode( list, &node );
3085         ok( r == S_OK, "nextNode returned wrong code\n");
3086     }
3087     else
3088         ok( FALSE, "no list\n");
3089
3090     if (node)
3091     {
3092         type = NODE_INVALID;
3093         r = IXMLDOMNode_get_nodeType( node, &type);
3094         ok( r == S_OK, "getNamedItem returned wrong code\n");
3095         ok( type == NODE_ELEMENT, "node not text\n");
3096
3097         r = IXMLDOMNode_hasChildNodes( node, NULL );
3098         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3099
3100         EXPECT_CHILDREN(node);
3101
3102         str = NULL;
3103         r = IXMLDOMNode_get_baseName( node, &str );
3104         ok( r == S_OK, "get_baseName returned wrong code\n");
3105         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3106         SysFreeString(str);
3107     }
3108     else
3109         ok( FALSE, "no node\n");
3110
3111     if (node)
3112         IXMLDOMNode_Release( node );
3113     if (list)
3114         IXMLDOMNodeList_Release( list );
3115     if (element)
3116         IXMLDOMElement_Release( element );
3117
3118     b = FALSE;
3119     str = SysAllocString( szComplete5 );
3120     r = IXMLDOMDocument_loadXML( doc, str, &b );
3121     ok( r == S_OK, "loadXML failed\n");
3122     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3123     SysFreeString( str );
3124
3125     EXPECT_CHILDREN(doc);
3126
3127     r = IXMLDOMDocument_get_documentElement( doc, &element );
3128     ok( r == S_OK, "should be a document element\n");
3129     ok( element != NULL, "should be an element\n");
3130
3131     if (element)
3132     {
3133         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3134         BSTR tag = NULL;
3135
3136         /* check if the tag is correct */
3137         r = IXMLDOMElement_get_tagName( element, &tag );
3138         ok( r == S_OK, "couldn't get tag name\n");
3139         ok( tag != NULL, "tag was null\n");
3140         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3141         SysFreeString( tag );
3142     }
3143
3144     if (element)
3145         IXMLDOMElement_Release( element );
3146     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3147
3148     free_bstrs();
3149 }
3150
3151 typedef struct {
3152     DOMNodeType type;
3153     REFIID iid;
3154 } refcount_test_t;
3155
3156 static const refcount_test_t refcount_test[] = {
3157     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3158     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3159     { NODE_TEXT,                   &IID_IXMLDOMText },
3160     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3161     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3162     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3163     { NODE_COMMENT,                &IID_IXMLDOMComment },
3164     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3165     { NODE_INVALID,                &IID_NULL }
3166 };
3167
3168 static void test_refs(void)
3169 {
3170     IXMLDOMImplementation *impl, *impl2;
3171     IXMLDOMElement *element, *elem2;
3172     IXMLDOMNodeList *node_list = NULL;
3173     IXMLDOMNode *node, *node2, *node3;
3174     const refcount_test_t *ptr;
3175     IXMLDOMDocument *doc;
3176     IUnknown *unk, *unk2;
3177     VARIANT_BOOL b;
3178     HRESULT hr;
3179     LONG ref;
3180
3181     doc = create_document(&IID_IXMLDOMDocument);
3182     if (!doc) return;
3183
3184     ptr = refcount_test;
3185     while (ptr->type != NODE_INVALID)
3186     {
3187         IUnknown *node_typed, *node_typed2;
3188         IDispatchEx *dispex, *dispex2;
3189         IDispatch *disp, *disp2;
3190         VARIANT type;
3191
3192         V_VT(&type) = VT_I1;
3193         V_I1(&type) = ptr->type;
3194
3195         EXPECT_REF(doc, 1);
3196         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3197         EXPECT_HR(hr, S_OK);
3198         EXPECT_REF(doc, 1);
3199         EXPECT_REF(node, 1);
3200
3201         /* try IDispatch and IUnknown from IXMLDOMNode */
3202         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3203         EXPECT_HR(hr, S_OK);
3204         EXPECT_REF(unk, 2);
3205 todo_wine {
3206         EXPECT_REF(node, 1);
3207         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3208 }
3209         EXPECT_REF(unk, 2);
3210         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3211         EXPECT_HR(hr, S_OK);
3212         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3213         EXPECT_REF(unk, 3);
3214         todo_wine EXPECT_REF(disp, 1);
3215
3216         EXPECT_REF(unk, 3);
3217         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3218         EXPECT_HR(hr, S_OK);
3219         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3220         EXPECT_REF(unk, 4);
3221         todo_wine EXPECT_REF(disp2, 1);
3222
3223         IDispatch_Release(disp);
3224         IDispatch_Release(disp2);
3225
3226         /* get IXMLDOMNode from this IUnknown */
3227         EXPECT_REF(unk, 2);
3228         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3229         EXPECT_HR(hr, S_OK);
3230         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3231         EXPECT_REF(unk, 3);
3232         todo_wine EXPECT_REF(node2, 1);
3233
3234         EXPECT_REF(unk, 3);
3235         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3236         EXPECT_HR(hr, S_OK);
3237         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3238         EXPECT_REF(unk, 4);
3239         todo_wine EXPECT_REF(node3, 1);
3240
3241         IXMLDOMNode_Release(node2);
3242         IXMLDOMNode_Release(node3);
3243
3244         /* try IDispatchEx from IUnknown */
3245         EXPECT_REF(unk, 2);
3246         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3247         EXPECT_HR(hr, S_OK);
3248         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3249         EXPECT_REF(unk, 3);
3250         todo_wine EXPECT_REF(dispex, 1);
3251
3252         EXPECT_REF(unk, 3);
3253         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3254         EXPECT_HR(hr, S_OK);
3255         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3256         EXPECT_REF(unk, 4);
3257         todo_wine EXPECT_REF(dispex2, 1);
3258
3259         IDispatch_Release(dispex);
3260         IDispatch_Release(dispex2);
3261
3262         /* try corresponding IXMLDOM* */
3263         EXPECT_REF(unk, 2);
3264         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3265         EXPECT_HR(hr, S_OK);
3266         EXPECT_REF(unk, 3);
3267         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3268         EXPECT_HR(hr, S_OK);
3269         EXPECT_REF(unk, 4);
3270         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3271         IUnknown_Release(node_typed);
3272         IUnknown_Release(node_typed2);
3273
3274         /* try invalid IXMLDOM* */
3275         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3276         EXPECT_HR(hr, E_NOINTERFACE);
3277
3278         IUnknown_Release(unk);
3279
3280         EXPECT_REF(node, 1);
3281         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3282         EXPECT_HR(hr, S_OK);
3283         EXPECT_REF(node, 2);
3284         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3285
3286         EXPECT_REF(node, 2);
3287         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3288         EXPECT_HR(hr, S_OK);
3289         EXPECT_REF(node, 3);
3290 todo_wine {
3291         EXPECT_REF(node_typed, 2);
3292         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3293 }
3294         IUnknown_Release(node_typed);
3295
3296         IXMLDOMNode_Release(node2);
3297         IXMLDOMNode_Release(node);
3298
3299         ptr++;
3300     }
3301
3302     EXPECT_REF(doc, 1);
3303     ref = IXMLDOMDocument_Release(doc);
3304     ok( ref == 0, "ref %d\n", ref);
3305
3306     /* check IUnknown after releasing DOM iface */
3307     doc = create_document(&IID_IXMLDOMDocument);
3308     EXPECT_REF(doc, 1);
3309     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3310     EXPECT_HR(hr, S_OK);
3311 todo_wine {
3312     EXPECT_REF(unk, 3);
3313     EXPECT_REF(doc, 1);
3314 }
3315     IXMLDOMDocument_Release(doc);
3316     EXPECT_REF(unk, 1);
3317     IUnknown_Release(unk);
3318
3319     doc = create_document(&IID_IXMLDOMDocument);
3320     if (!doc) return;
3321
3322     EXPECT_REF(doc, 1);
3323     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3324     EXPECT_HR(hr, S_OK);
3325 todo_wine {
3326     EXPECT_REF(unk, 3);
3327     EXPECT_REF(doc, 1);
3328 }
3329     IUnknown_Release(unk);
3330
3331     /* IXMLDOMImplementation */
3332     EXPECT_REF(doc, 1);
3333     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3334     EXPECT_HR(hr, S_OK);
3335     EXPECT_REF(doc, 1);
3336     EXPECT_REF(impl, 1);
3337     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3338     EXPECT_HR(hr, S_OK);
3339     EXPECT_REF(doc, 1);
3340     EXPECT_REF(impl2, 1);
3341     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3342     IXMLDOMImplementation_Release(impl);
3343     IXMLDOMImplementation_Release(impl2);
3344
3345     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3346     EXPECT_HR(hr, S_OK);
3347     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3348
3349     EXPECT_REF(doc, 1);
3350     IXMLDOMDocument_AddRef( doc );
3351     EXPECT_REF(doc, 2);
3352     IXMLDOMDocument_AddRef( doc );
3353     EXPECT_REF(doc, 3);
3354
3355     IXMLDOMDocument_Release( doc );
3356     IXMLDOMDocument_Release( doc );
3357
3358     EXPECT_REF(doc, 1);
3359     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3360     EXPECT_HR(hr, S_OK);
3361 todo_wine {
3362     EXPECT_REF(unk, 3);
3363     EXPECT_REF(doc, 1);
3364 }
3365     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3366     EXPECT_HR(hr, S_OK);
3367 todo_wine {
3368     EXPECT_REF(doc, 1);
3369     EXPECT_REF(element, 2);
3370 }
3371     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3372     EXPECT_HR(hr, S_OK);
3373
3374 todo_wine {
3375     EXPECT_REF(doc, 1);
3376     EXPECT_REF(element, 2);
3377     EXPECT_REF(elem2, 2);
3378 }
3379     IXMLDOMElement_AddRef(element);
3380     todo_wine EXPECT_REF(element, 3);
3381     IXMLDOMElement_Release(element);
3382
3383     /* get IUnknown from a node doesn't touch node instance refcount */
3384     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3385     EXPECT_HR(hr, S_OK);
3386     EXPECT_REF(element, 2);
3387 todo_wine {
3388     EXPECT_REF(unk, 4);
3389     EXPECT_REF(elem2, 2);
3390 }
3391     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3392     EXPECT_HR(hr, S_OK);
3393 todo_wine {
3394     EXPECT_REF(unk, 5);
3395     EXPECT_REF(unk2, 5);
3396 }
3397     EXPECT_REF(element, 2);
3398     EXPECT_REF(elem2, 2);
3399
3400     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3401
3402     IUnknown_Release(unk);
3403     IUnknown_Release(unk2);
3404
3405     /* IUnknown refcount is not affected by node refcount */
3406     todo_wine EXPECT_REF(unk2, 3);
3407     IXMLDOMElement_AddRef(elem2);
3408     todo_wine EXPECT_REF(unk2, 3);
3409     IXMLDOMElement_Release(elem2);
3410
3411     IXMLDOMElement_Release(elem2);
3412     todo_wine EXPECT_REF(unk2, 2);
3413
3414     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3415     EXPECT_HR(hr, S_OK);
3416
3417     todo_wine EXPECT_REF(element, 2);
3418     EXPECT_REF(node_list, 1);
3419
3420     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3421     EXPECT_HR(hr, S_OK);
3422     EXPECT_REF(node_list, 1);
3423     EXPECT_REF(node, 1);
3424
3425     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3426     EXPECT_HR(hr, S_OK);
3427     EXPECT_REF(node_list, 1);
3428     EXPECT_REF(node2, 1);
3429
3430     ref = IXMLDOMNode_Release( node );
3431     ok( ref == 0, "ref %d\n", ref );
3432     ref = IXMLDOMNode_Release( node2 );
3433     ok( ref == 0, "ref %d\n", ref );
3434
3435     ref = IXMLDOMNodeList_Release( node_list );
3436     ok( ref == 0, "ref %d\n", ref );
3437
3438     ok( node != node2, "node %p node2 %p\n", node, node2 );
3439
3440     ref = IXMLDOMDocument_Release( doc );
3441     todo_wine ok( ref == 0, "ref %d\n", ref );
3442
3443     todo_wine EXPECT_REF(element, 2);
3444
3445     /* IUnknown must be unique however we obtain it */
3446     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3447     EXPECT_HR(hr, S_OK);
3448     EXPECT_REF(element, 2);
3449     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3450     EXPECT_HR(hr, S_OK);
3451     todo_wine EXPECT_REF(element, 2);
3452     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3453     EXPECT_HR(hr, S_OK);
3454     todo_wine EXPECT_REF(element, 2);
3455     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3456     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3457
3458     IUnknown_Release( unk2 );
3459     IUnknown_Release( unk );
3460     IXMLDOMNode_Release( node );
3461     todo_wine EXPECT_REF(element, 2);
3462
3463     IXMLDOMElement_Release( element );
3464
3465     free_bstrs();
3466 }
3467
3468 static void test_create(void)
3469 {
3470     static const WCHAR szOne[] = {'1',0};
3471     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3472     HRESULT r;
3473     VARIANT var;
3474     BSTR str, name;
3475     IXMLDOMDocument *doc;
3476     IXMLDOMElement *element;
3477     IXMLDOMComment *comment;
3478     IXMLDOMText *text;
3479     IXMLDOMCDATASection *cdata;
3480     IXMLDOMNode *root, *node, *child;
3481     IXMLDOMNamedNodeMap *attr_map;
3482     IUnknown *unk;
3483     LONG ref;
3484     LONG num;
3485
3486     doc = create_document(&IID_IXMLDOMDocument);
3487     if (!doc) return;
3488
3489     EXPECT_REF(doc, 1);
3490
3491     /* types not supported for creation */
3492     V_VT(&var) = VT_I1;
3493     V_I1(&var) = NODE_DOCUMENT;
3494     node = (IXMLDOMNode*)0x1;
3495     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3496     ok( r == E_INVALIDARG, "returns %08x\n", r );
3497     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3498
3499     V_VT(&var) = VT_I1;
3500     V_I1(&var) = NODE_DOCUMENT_TYPE;
3501     node = (IXMLDOMNode*)0x1;
3502     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3503     ok( r == E_INVALIDARG, "returns %08x\n", r );
3504     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3505
3506     V_VT(&var) = VT_I1;
3507     V_I1(&var) = NODE_ENTITY;
3508     node = (IXMLDOMNode*)0x1;
3509     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3510     ok( r == E_INVALIDARG, "returns %08x\n", r );
3511     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3512
3513     V_VT(&var) = VT_I1;
3514     V_I1(&var) = NODE_NOTATION;
3515     node = (IXMLDOMNode*)0x1;
3516     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3517     ok( r == E_INVALIDARG, "returns %08x\n", r );
3518     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3519
3520     /* NODE_COMMENT */
3521     V_VT(&var) = VT_I1;
3522     V_I1(&var) = NODE_COMMENT;
3523     node = NULL;
3524     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3525     ok( r == S_OK, "returns %08x\n", r );
3526     ok( node != NULL, "\n");
3527
3528     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3529     ok( r == S_OK, "returns %08x\n", r );
3530     IXMLDOMNode_Release(node);
3531
3532     str = NULL;
3533     r = IXMLDOMComment_get_data(comment, &str);
3534     ok( r == S_OK, "returns %08x\n", r );
3535     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3536     IXMLDOMComment_Release(comment);
3537     SysFreeString(str);
3538
3539     node = (IXMLDOMNode*)0x1;
3540     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3541     ok( r == S_OK, "returns %08x\n", r );
3542
3543     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3544     ok( r == S_OK, "returns %08x\n", r );
3545     IXMLDOMNode_Release(node);
3546
3547     str = NULL;
3548     r = IXMLDOMComment_get_data(comment, &str);
3549     ok( r == S_OK, "returns %08x\n", r );
3550     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3551     IXMLDOMComment_Release(comment);
3552     SysFreeString(str);
3553
3554     node = (IXMLDOMNode*)0x1;
3555     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3556     ok( r == S_OK, "returns %08x\n", r );
3557
3558     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3559     ok( r == S_OK, "returns %08x\n", r );
3560     IXMLDOMNode_Release(node);
3561
3562     str = NULL;
3563     r = IXMLDOMComment_get_data(comment, &str);
3564     ok( r == S_OK, "returns %08x\n", r );
3565     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3566     IXMLDOMComment_Release(comment);
3567     SysFreeString(str);
3568
3569     /* NODE_TEXT */
3570     V_VT(&var) = VT_I1;
3571     V_I1(&var) = NODE_TEXT;
3572     node = NULL;
3573     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3574     ok( r == S_OK, "returns %08x\n", r );
3575     ok( node != NULL, "\n");
3576
3577     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3578     ok( r == S_OK, "returns %08x\n", r );
3579     IXMLDOMNode_Release(node);
3580
3581     str = NULL;
3582     r = IXMLDOMText_get_data(text, &str);
3583     ok( r == S_OK, "returns %08x\n", r );
3584     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3585     IXMLDOMText_Release(text);
3586     SysFreeString(str);
3587
3588     node = (IXMLDOMNode*)0x1;
3589     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3590     ok( r == S_OK, "returns %08x\n", r );
3591
3592     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3593     ok( r == S_OK, "returns %08x\n", r );
3594     IXMLDOMNode_Release(node);
3595
3596     str = NULL;
3597     r = IXMLDOMText_get_data(text, &str);
3598     ok( r == S_OK, "returns %08x\n", r );
3599     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3600     IXMLDOMText_Release(text);
3601     SysFreeString(str);
3602
3603     node = (IXMLDOMNode*)0x1;
3604     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3605     ok( r == S_OK, "returns %08x\n", r );
3606
3607     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3608     ok( r == S_OK, "returns %08x\n", r );
3609     IXMLDOMNode_Release(node);
3610
3611     str = NULL;
3612     r = IXMLDOMText_get_data(text, &str);
3613     ok( r == S_OK, "returns %08x\n", r );
3614     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3615     IXMLDOMText_Release(text);
3616     SysFreeString(str);
3617
3618     /* NODE_CDATA_SECTION */
3619     V_VT(&var) = VT_I1;
3620     V_I1(&var) = NODE_CDATA_SECTION;
3621     node = NULL;
3622     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3623     ok( r == S_OK, "returns %08x\n", r );
3624     ok( node != NULL, "\n");
3625
3626     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3627     ok( r == S_OK, "returns %08x\n", r );
3628     IXMLDOMNode_Release(node);
3629
3630     str = NULL;
3631     r = IXMLDOMCDATASection_get_data(cdata, &str);
3632     ok( r == S_OK, "returns %08x\n", r );
3633     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3634     IXMLDOMCDATASection_Release(cdata);
3635     SysFreeString(str);
3636
3637     node = (IXMLDOMNode*)0x1;
3638     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3639     ok( r == S_OK, "returns %08x\n", r );
3640
3641     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3642     ok( r == S_OK, "returns %08x\n", r );
3643     IXMLDOMNode_Release(node);
3644
3645     str = NULL;
3646     r = IXMLDOMCDATASection_get_data(cdata, &str);
3647     ok( r == S_OK, "returns %08x\n", r );
3648     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3649     IXMLDOMCDATASection_Release(cdata);
3650     SysFreeString(str);
3651
3652     node = (IXMLDOMNode*)0x1;
3653     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3654     ok( r == S_OK, "returns %08x\n", r );
3655
3656     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3657     ok( r == S_OK, "returns %08x\n", r );
3658     IXMLDOMNode_Release(node);
3659
3660     str = NULL;
3661     r = IXMLDOMCDATASection_get_data(cdata, &str);
3662     ok( r == S_OK, "returns %08x\n", r );
3663     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3664     IXMLDOMCDATASection_Release(cdata);
3665     SysFreeString(str);
3666
3667     /* NODE_ATTRIBUTE */
3668     V_VT(&var) = VT_I1;
3669     V_I1(&var) = NODE_ATTRIBUTE;
3670     node = (IXMLDOMNode*)0x1;
3671     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3672     ok( r == E_FAIL, "returns %08x\n", r );
3673     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3674
3675     V_VT(&var) = VT_I1;
3676     V_I1(&var) = NODE_ATTRIBUTE;
3677     node = (IXMLDOMNode*)0x1;
3678     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3679     ok( r == E_FAIL, "returns %08x\n", r );
3680     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3681
3682     V_VT(&var) = VT_I1;
3683     V_I1(&var) = NODE_ATTRIBUTE;
3684     str = SysAllocString( szlc );
3685     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3686     ok( r == S_OK, "returns %08x\n", r );
3687     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3688     SysFreeString(str);
3689
3690     /* a name is required for attribute, try a BSTR with first null wchar */
3691     V_VT(&var) = VT_I1;
3692     V_I1(&var) = NODE_ATTRIBUTE;
3693     str = SysAllocString( szstr1 );
3694     str[0] = 0;
3695     node = (IXMLDOMNode*)0x1;
3696     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3697     ok( r == E_FAIL, "returns %08x\n", r );
3698     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3699     SysFreeString(str);
3700
3701     /* NODE_PROCESSING_INSTRUCTION */
3702     V_VT(&var) = VT_I1;
3703     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3704     node = (IXMLDOMNode*)0x1;
3705     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3706     ok( r == E_FAIL, "returns %08x\n", r );
3707     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3708
3709     V_VT(&var) = VT_I1;
3710     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3711     node = (IXMLDOMNode*)0x1;
3712     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3713     ok( r == E_FAIL, "returns %08x\n", r );
3714     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3715
3716     V_VT(&var) = VT_I1;
3717     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3718     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3719     ok( r == E_INVALIDARG, "returns %08x\n", r );
3720
3721     /* NODE_ENTITY_REFERENCE */
3722     V_VT(&var) = VT_I1;
3723     V_I1(&var) = NODE_ENTITY_REFERENCE;
3724     node = (IXMLDOMNode*)0x1;
3725     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3726     ok( r == E_FAIL, "returns %08x\n", r );
3727     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3728
3729     V_VT(&var) = VT_I1;
3730     V_I1(&var) = NODE_ENTITY_REFERENCE;
3731     node = (IXMLDOMNode*)0x1;
3732     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3733     ok( r == E_FAIL, "returns %08x\n", r );
3734     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3735
3736     /* NODE_ELEMENT */
3737     V_VT(&var) = VT_I1;
3738     V_I1(&var) = NODE_ELEMENT;
3739     node = (IXMLDOMNode*)0x1;
3740     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3741     ok( r == E_FAIL, "returns %08x\n", r );
3742     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3743
3744     V_VT(&var) = VT_I1;
3745     V_I1(&var) = NODE_ELEMENT;
3746     node = (IXMLDOMNode*)0x1;
3747     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3748     ok( r == E_FAIL, "returns %08x\n", r );
3749     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3750
3751     V_VT(&var) = VT_I1;
3752     V_I1(&var) = NODE_ELEMENT;
3753     str = SysAllocString( szlc );
3754     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3755     ok( r == S_OK, "returns %08x\n", r );
3756     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3757
3758     V_VT(&var) = VT_I1;
3759     V_I1(&var) = NODE_ELEMENT;
3760     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3761     ok( r == E_INVALIDARG, "returns %08x\n", r );
3762
3763     V_VT(&var) = VT_R4;
3764     V_R4(&var) = NODE_ELEMENT;
3765     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3766     ok( r == S_OK, "returns %08x\n", r );
3767     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3768
3769     V_VT(&var) = VT_BSTR;
3770     V_BSTR(&var) = SysAllocString( szOne );
3771     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3772     ok( r == S_OK, "returns %08x\n", r );
3773     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3774     VariantClear(&var);
3775
3776     V_VT(&var) = VT_BSTR;
3777     V_BSTR(&var) = SysAllocString( szOneGarbage );
3778     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3779     ok( r == E_INVALIDARG, "returns %08x\n", r );
3780     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3781     VariantClear(&var);
3782
3783     V_VT(&var) = VT_I4;
3784     V_I4(&var) = NODE_ELEMENT;
3785     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3786     ok( r == S_OK, "returns %08x\n", r );
3787
3788     EXPECT_REF(doc, 1);
3789     r = IXMLDOMDocument_appendChild( doc, node, &root );
3790     ok( r == S_OK, "returns %08x\n", r );
3791     ok( node == root, "%p %p\n", node, root );
3792     EXPECT_REF(doc, 1);
3793
3794     EXPECT_REF(node, 2);
3795
3796     ref = IXMLDOMNode_Release( node );
3797     ok(ref == 1, "ref %d\n", ref);
3798     SysFreeString( str );
3799
3800     V_VT(&var) = VT_I4;
3801     V_I4(&var) = NODE_ELEMENT;
3802     str = SysAllocString( szbs );
3803     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3804     ok( r == S_OK, "returns %08x\n", r );
3805     SysFreeString( str );
3806
3807     EXPECT_REF(node, 1);
3808
3809     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3810     ok( r == S_OK, "returns %08x\n", r );
3811
3812     EXPECT_REF(unk, 2);
3813
3814     V_VT(&var) = VT_EMPTY;
3815     child = NULL;
3816     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3817     ok( r == S_OK, "returns %08x\n", r );
3818     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3819
3820     todo_wine EXPECT_REF(unk, 4);
3821
3822     IXMLDOMNode_Release( child );
3823     IUnknown_Release( unk );
3824
3825     V_VT(&var) = VT_NULL;
3826     V_DISPATCH(&var) = (IDispatch*)node;
3827     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3828     ok( r == S_OK, "returns %08x\n", r );
3829     ok( node == child, "%p %p\n", node, child );
3830     IXMLDOMNode_Release( child );
3831
3832     V_VT(&var) = VT_NULL;
3833     V_DISPATCH(&var) = (IDispatch*)node;
3834     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3835     ok( r == S_OK, "returns %08x\n", r );
3836     IXMLDOMNode_Release( node );
3837
3838     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3839     ok( r == S_OK, "returns %08x\n", r );
3840
3841     r = IXMLDOMElement_get_attributes( element, &attr_map );
3842     ok( r == S_OK, "returns %08x\n", r );
3843     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3844     ok( r == S_OK, "returns %08x\n", r );
3845     ok( num == 0, "num %d\n", num );
3846     IXMLDOMNamedNodeMap_Release( attr_map );
3847
3848     V_VT(&var) = VT_BSTR;
3849     V_BSTR(&var) = SysAllocString( szstr1 );
3850     name = SysAllocString( szdl );
3851     r = IXMLDOMElement_setAttribute( element, name, var );
3852     ok( r == S_OK, "returns %08x\n", r );
3853     r = IXMLDOMElement_get_attributes( element, &attr_map );
3854     ok( r == S_OK, "returns %08x\n", r );
3855     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3856     ok( r == S_OK, "returns %08x\n", r );
3857     ok( num == 1, "num %d\n", num );
3858     IXMLDOMNamedNodeMap_Release( attr_map );
3859     VariantClear(&var);
3860
3861     V_VT(&var) = VT_BSTR;
3862     V_BSTR(&var) = SysAllocString( szstr2 );
3863     r = IXMLDOMElement_setAttribute( element, name, var );
3864     ok( r == S_OK, "returns %08x\n", r );
3865     r = IXMLDOMElement_get_attributes( element, &attr_map );
3866     ok( r == S_OK, "returns %08x\n", r );
3867     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3868     ok( r == S_OK, "returns %08x\n", r );
3869     ok( num == 1, "num %d\n", num );
3870     IXMLDOMNamedNodeMap_Release( attr_map );
3871     VariantClear(&var);
3872     r = IXMLDOMElement_getAttribute( element, name, &var );
3873     ok( r == S_OK, "returns %08x\n", r );
3874     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3875     VariantClear(&var);
3876     SysFreeString(name);
3877
3878     V_VT(&var) = VT_BSTR;
3879     V_BSTR(&var) = SysAllocString( szstr1 );
3880     name = SysAllocString( szlc );
3881     r = IXMLDOMElement_setAttribute( element, name, var );
3882     ok( r == S_OK, "returns %08x\n", r );
3883     r = IXMLDOMElement_get_attributes( element, &attr_map );
3884     ok( r == S_OK, "returns %08x\n", r );
3885     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3886     ok( r == S_OK, "returns %08x\n", r );
3887     ok( num == 2, "num %d\n", num );
3888     IXMLDOMNamedNodeMap_Release( attr_map );
3889     VariantClear(&var);
3890     SysFreeString(name);
3891
3892     V_VT(&var) = VT_I4;
3893     V_I4(&var) = 10;
3894     name = SysAllocString( szbs );
3895     r = IXMLDOMElement_setAttribute( element, name, var );
3896     ok( r == S_OK, "returns %08x\n", r );
3897     VariantClear(&var);
3898     r = IXMLDOMElement_getAttribute( element, name, &var );
3899     ok( r == S_OK, "returns %08x\n", r );
3900     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3901     VariantClear(&var);
3902     SysFreeString(name);
3903
3904     /* Create an Attribute */
3905     V_VT(&var) = VT_I4;
3906     V_I4(&var) = NODE_ATTRIBUTE;
3907     str = SysAllocString( szAttribute );
3908     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3909     ok( r == S_OK, "returns %08x\n", r );
3910     ok( node != NULL, "node was null\n");
3911     SysFreeString(str);
3912
3913     IXMLDOMElement_Release( element );
3914     IXMLDOMNode_Release( root );
3915     IXMLDOMDocument_Release( doc );
3916 }
3917
3918 static void test_getElementsByTagName(void)
3919 {
3920     IXMLDOMNodeList *node_list;
3921     IXMLDOMDocument *doc;
3922     IXMLDOMElement *elem;
3923     WCHAR buff[100];
3924     VARIANT_BOOL b;
3925     HRESULT r;
3926     LONG len;
3927     BSTR str;
3928
3929     doc = create_document(&IID_IXMLDOMDocument);
3930     if (!doc) return;
3931
3932     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3933     ok( r == S_OK, "loadXML failed\n");
3934     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3935
3936     str = SysAllocString( szstar );
3937
3938     /* null arguments cases */
3939     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3940     ok( r == E_INVALIDARG, "ret %08x\n", r );
3941     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
3942     ok( r == E_INVALIDARG, "ret %08x\n", r );
3943
3944     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3945     ok( r == S_OK, "ret %08x\n", r );
3946     r = IXMLDOMNodeList_get_length( node_list, &len );
3947     ok( r == S_OK, "ret %08x\n", r );
3948     ok( len == 6, "len %d\n", len );
3949
3950     IXMLDOMNodeList_Release( node_list );
3951     SysFreeString( str );
3952
3953     /* broken query BSTR */
3954     memcpy(&buff[2], szstar, sizeof(szstar));
3955     /* just a big length */
3956     *(DWORD*)buff = 0xf0f0;
3957     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3958     ok( r == S_OK, "ret %08x\n", r );
3959     r = IXMLDOMNodeList_get_length( node_list, &len );
3960     ok( r == S_OK, "ret %08x\n", r );
3961     ok( len == 6, "len %d\n", len );
3962     IXMLDOMNodeList_Release( node_list );
3963
3964     str = SysAllocString( szbs );
3965     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3966     ok( r == S_OK, "ret %08x\n", r );
3967     r = IXMLDOMNodeList_get_length( node_list, &len );
3968     ok( r == S_OK, "ret %08x\n", r );
3969     ok( len == 1, "len %d\n", len );
3970     IXMLDOMNodeList_Release( node_list );
3971     SysFreeString( str );
3972
3973     str = SysAllocString( szdl );
3974     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3975     ok( r == S_OK, "ret %08x\n", r );
3976     r = IXMLDOMNodeList_get_length( node_list, &len );
3977     ok( r == S_OK, "ret %08x\n", r );
3978     ok( len == 0, "len %d\n", len );
3979     IXMLDOMNodeList_Release( node_list );
3980     SysFreeString( str );
3981
3982     str = SysAllocString( szstr1 );
3983     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
3984     ok( r == S_OK, "ret %08x\n", r );
3985     r = IXMLDOMNodeList_get_length( node_list, &len );
3986     ok( r == S_OK, "ret %08x\n", r );
3987     ok( len == 0, "len %d\n", len );
3988     IXMLDOMNodeList_Release( node_list );
3989     SysFreeString( str );
3990
3991     /* test for element */
3992     r = IXMLDOMDocument_get_documentElement(doc, &elem);
3993     ok( r == S_OK, "ret %08x\n", r );
3994
3995     str = SysAllocString( szstar );
3996
3997     /* null arguments cases */
3998     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3999     ok( r == E_INVALIDARG, "ret %08x\n", r );
4000     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
4001     ok( r == E_INVALIDARG, "ret %08x\n", r );
4002
4003     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
4004     ok( r == S_OK, "ret %08x\n", r );
4005     r = IXMLDOMNodeList_get_length( node_list, &len );
4006     ok( r == S_OK, "ret %08x\n", r );
4007     ok( len == 5, "len %d\n", len );
4008     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
4009     SysFreeString( str );
4010
4011     /* broken query BSTR */
4012     memcpy(&buff[2], szstar, sizeof(szstar));
4013     /* just a big length */
4014     *(DWORD*)buff = 0xf0f0;
4015     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
4016     ok( r == S_OK, "ret %08x\n", r );
4017     r = IXMLDOMNodeList_get_length( node_list, &len );
4018     ok( r == S_OK, "ret %08x\n", r );
4019     ok( len == 5, "len %d\n", len );
4020     IXMLDOMNodeList_Release( node_list );
4021
4022     IXMLDOMElement_Release(elem);
4023
4024     IXMLDOMDocument_Release( doc );
4025
4026     free_bstrs();
4027 }
4028
4029 static void test_get_text(void)
4030 {
4031     HRESULT r;
4032     BSTR str;
4033     VARIANT_BOOL b;
4034     IXMLDOMDocument *doc;
4035     IXMLDOMNode *node, *node2, *node3;
4036     IXMLDOMNode *nodeRoot;
4037     IXMLDOMNodeList *node_list;
4038     IXMLDOMNamedNodeMap *node_map;
4039     LONG len;
4040
4041     doc = create_document(&IID_IXMLDOMDocument);
4042     if (!doc) return;
4043
4044     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4045     ok( r == S_OK, "loadXML failed\n");
4046     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4047
4048     str = SysAllocString( szbs );
4049     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
4050     ok( r == S_OK, "ret %08x\n", r );
4051     SysFreeString(str);
4052
4053     /* Test to get all child node text. */
4054     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
4055     ok( r == S_OK, "ret %08x\n", r );
4056     if(r == S_OK)
4057     {
4058         r = IXMLDOMNode_get_text( nodeRoot, &str );
4059         ok( r == S_OK, "ret %08x\n", r );
4060         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
4061         SysFreeString(str);
4062
4063         IXMLDOMNode_Release(nodeRoot);
4064     }
4065
4066     r = IXMLDOMNodeList_get_length( node_list, NULL );
4067     ok( r == E_INVALIDARG, "ret %08x\n", r );
4068
4069     r = IXMLDOMNodeList_get_length( node_list, &len );
4070     ok( r == S_OK, "ret %08x\n", r );
4071     ok( len == 1, "expect 1 got %d\n", len );
4072
4073     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
4074     ok( r == E_INVALIDARG, "ret %08x\n", r );
4075
4076     r = IXMLDOMNodeList_nextNode( node_list, NULL );
4077     ok( r == E_INVALIDARG, "ret %08x\n", r );
4078
4079     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4080     ok( r == S_OK, "ret %08x\n", r );
4081     IXMLDOMNodeList_Release( node_list );
4082
4083     /* Invalid output parameter*/
4084     r = IXMLDOMNode_get_text( node, NULL );
4085     ok( r == E_INVALIDARG, "ret %08x\n", r );
4086
4087     r = IXMLDOMNode_get_text( node, &str );
4088     ok( r == S_OK, "ret %08x\n", r );
4089     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4090     SysFreeString(str);
4091
4092     r = IXMLDOMNode_get_attributes( node, &node_map );
4093     ok( r == S_OK, "ret %08x\n", r );
4094
4095     str = SysAllocString( szvr );
4096     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4097     ok( r == S_OK, "ret %08x\n", r );
4098     SysFreeString(str);
4099
4100     r = IXMLDOMNode_get_text( node2, &str );
4101     ok( r == S_OK, "ret %08x\n", r );
4102     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4103     SysFreeString(str);
4104
4105     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4106     ok( r == S_OK, "ret %08x\n", r );
4107
4108     r = IXMLDOMNode_get_text( node3, &str );
4109     ok( r == S_OK, "ret %08x\n", r );
4110     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4111     SysFreeString(str);
4112
4113
4114     IXMLDOMNode_Release( node3 );
4115     IXMLDOMNode_Release( node2 );
4116     IXMLDOMNamedNodeMap_Release( node_map );
4117     IXMLDOMNode_Release( node );
4118     IXMLDOMDocument_Release( doc );
4119
4120     free_bstrs();
4121 }
4122
4123 static void test_get_childNodes(void)
4124 {
4125     BSTR str;
4126     VARIANT_BOOL b;
4127     IXMLDOMDocument *doc;
4128     IXMLDOMElement *element;
4129     IXMLDOMNode *node, *node2;
4130     IXMLDOMNodeList *node_list, *node_list2;
4131     HRESULT hr;
4132     LONG len;
4133
4134     doc = create_document(&IID_IXMLDOMDocument);
4135     if (!doc) return;
4136
4137     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4138     EXPECT_HR(hr, S_OK);
4139     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4140
4141     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4142     EXPECT_HR(hr, S_OK);
4143
4144     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4145     EXPECT_HR(hr, S_OK);
4146
4147     hr = IXMLDOMNodeList_get_length( node_list, &len );
4148     EXPECT_HR(hr, S_OK);
4149     ok( len == 4, "len %d\n", len);
4150
4151     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4152     EXPECT_HR(hr, S_OK);
4153
4154     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4155     EXPECT_HR(hr, S_OK);
4156
4157     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4158     EXPECT_HR(hr, S_OK);
4159     ok( len == 0, "len %d\n", len);
4160
4161     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4162     EXPECT_HR(hr, S_FALSE);
4163
4164     IXMLDOMNodeList_Release( node_list2 );
4165     IXMLDOMNode_Release( node );
4166     IXMLDOMNodeList_Release( node_list );
4167     IXMLDOMElement_Release( element );
4168
4169     /* test for children of <?xml ..?> node */
4170     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4171     EXPECT_HR(hr, S_OK);
4172
4173     str = NULL;
4174     hr = IXMLDOMNode_get_nodeName(node, &str);
4175     EXPECT_HR(hr, S_OK);
4176     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4177     SysFreeString(str);
4178
4179     /* it returns empty but valid node list */
4180     node_list = (void*)0xdeadbeef;
4181     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4182     EXPECT_HR(hr, S_OK);
4183
4184     len = -1;
4185     hr = IXMLDOMNodeList_get_length(node_list, &len);
4186     EXPECT_HR(hr, S_OK);
4187     ok(len == 0, "got %d\n", len);
4188
4189     IXMLDOMNodeList_Release( node_list );
4190     IXMLDOMNode_Release(node);
4191
4192     IXMLDOMDocument_Release( doc );
4193     free_bstrs();
4194 }
4195
4196 static void test_get_firstChild(void)
4197 {
4198     static WCHAR xmlW[] = {'x','m','l',0};
4199     IXMLDOMDocument *doc;
4200     IXMLDOMNode *node;
4201     VARIANT_BOOL b;
4202     HRESULT r;
4203     BSTR str;
4204
4205     doc = create_document(&IID_IXMLDOMDocument);
4206     if (!doc) return;
4207
4208     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4209     ok( r == S_OK, "loadXML failed\n");
4210     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4211
4212     r = IXMLDOMDocument_get_firstChild( doc, &node );
4213     ok( r == S_OK, "ret %08x\n", r);
4214
4215     r = IXMLDOMNode_get_nodeName( node, &str );
4216     ok( r == S_OK, "ret %08x\n", r);
4217
4218     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4219
4220     SysFreeString(str);
4221     IXMLDOMNode_Release( node );
4222     IXMLDOMDocument_Release( doc );
4223
4224     free_bstrs();
4225 }
4226
4227 static void test_get_lastChild(void)
4228 {
4229     static WCHAR lcW[] = {'l','c',0};
4230     static WCHAR foW[] = {'f','o',0};
4231     IXMLDOMDocument *doc;
4232     IXMLDOMNode *node, *child;
4233     VARIANT_BOOL b;
4234     HRESULT r;
4235     BSTR str;
4236
4237     doc = create_document(&IID_IXMLDOMDocument);
4238     if (!doc) return;
4239
4240     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4241     ok( r == S_OK, "loadXML failed\n");
4242     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4243
4244     r = IXMLDOMDocument_get_lastChild( doc, &node );
4245     ok( r == S_OK, "ret %08x\n", r);
4246
4247     r = IXMLDOMNode_get_nodeName( node, &str );
4248     ok( r == S_OK, "ret %08x\n", r);
4249
4250     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4251     SysFreeString(str);
4252
4253     r = IXMLDOMNode_get_lastChild( node, &child );
4254     ok( r == S_OK, "ret %08x\n", r);
4255
4256     r = IXMLDOMNode_get_nodeName( child, &str );
4257     ok( r == S_OK, "ret %08x\n", r);
4258
4259     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4260     SysFreeString(str);
4261
4262     IXMLDOMNode_Release( child );
4263     IXMLDOMNode_Release( node );
4264     IXMLDOMDocument_Release( doc );
4265
4266     free_bstrs();
4267 }
4268
4269 static void test_removeChild(void)
4270 {
4271     HRESULT r;
4272     VARIANT_BOOL b;
4273     IXMLDOMDocument *doc;
4274     IXMLDOMElement *element, *lc_element;
4275     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4276     IXMLDOMNodeList *root_list, *fo_list;
4277
4278     doc = create_document(&IID_IXMLDOMDocument);
4279     if (!doc) return;
4280
4281     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4282     ok( r == S_OK, "loadXML failed\n");
4283     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4284
4285     r = IXMLDOMDocument_get_documentElement( doc, &element );
4286     ok( r == S_OK, "ret %08x\n", r);
4287     todo_wine EXPECT_REF(element, 2);
4288
4289     r = IXMLDOMElement_get_childNodes( element, &root_list );
4290     ok( r == S_OK, "ret %08x\n", r);
4291     EXPECT_REF(root_list, 1);
4292
4293     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4294     ok( r == S_OK, "ret %08x\n", r);
4295     EXPECT_REF(fo_node, 1);
4296
4297     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4298     ok( r == S_OK, "ret %08x\n", r);
4299     EXPECT_REF(fo_list, 1);
4300
4301     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4302     ok( r == S_OK, "ret %08x\n", r);
4303     EXPECT_REF(ba_node, 1);
4304
4305     /* invalid parameter: NULL ptr */
4306     removed_node = (void*)0xdeadbeef;
4307     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4308     ok( r == E_INVALIDARG, "ret %08x\n", r );
4309     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4310
4311     /* ba_node is a descendant of element, but not a direct child. */
4312     removed_node = (void*)0xdeadbeef;
4313     EXPECT_REF(ba_node, 1);
4314     EXPECT_CHILDREN(fo_node);
4315     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4316     ok( r == E_INVALIDARG, "ret %08x\n", r );
4317     ok( removed_node == NULL, "%p\n", removed_node );
4318     EXPECT_REF(ba_node, 1);
4319     EXPECT_CHILDREN(fo_node);
4320
4321     EXPECT_REF(ba_node, 1);
4322     EXPECT_REF(fo_node, 1);
4323     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4324     ok( r == S_OK, "ret %08x\n", r);
4325     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4326     EXPECT_REF(fo_node, 2);
4327     EXPECT_REF(ba_node, 1);
4328
4329     /* try removing already removed child */
4330     temp_node = (void*)0xdeadbeef;
4331     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4332     ok( r == E_INVALIDARG, "ret %08x\n", r);
4333     ok( temp_node == NULL, "%p\n", temp_node );
4334     IXMLDOMNode_Release( fo_node );
4335
4336     /* the removed node has no parent anymore */
4337     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4338     ok( r == S_FALSE, "ret %08x\n", r);
4339     ok( temp_node == NULL, "%p\n", temp_node );
4340
4341     IXMLDOMNode_Release( removed_node );
4342     IXMLDOMNode_Release( ba_node );
4343     IXMLDOMNodeList_Release( fo_list );
4344
4345     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4346     ok( r == S_OK, "ret %08x\n", r);
4347
4348     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4349     ok( r == S_OK, "ret %08x\n", r);
4350
4351     /* MS quirk: passing wrong interface pointer works, too */
4352     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4353     ok( r == S_OK, "ret %08x\n", r);
4354     IXMLDOMElement_Release( lc_element );
4355
4356     temp_node = (void*)0xdeadbeef;
4357     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4358     ok( r == S_FALSE, "ret %08x\n", r);
4359     ok( temp_node == NULL, "%p\n", temp_node );
4360
4361     IXMLDOMNode_Release( lc_node );
4362     IXMLDOMNodeList_Release( root_list );
4363     IXMLDOMElement_Release( element );
4364     IXMLDOMDocument_Release( doc );
4365
4366     free_bstrs();
4367 }
4368
4369 static void test_replaceChild(void)
4370 {
4371     HRESULT r;
4372     VARIANT_BOOL b;
4373     IXMLDOMDocument *doc;
4374     IXMLDOMElement *element, *ba_element;
4375     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4376     IXMLDOMNodeList *root_list, *fo_list;
4377     IUnknown * unk1, *unk2;
4378     LONG len;
4379
4380     doc = create_document(&IID_IXMLDOMDocument);
4381     if (!doc) return;
4382
4383     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4384     ok( r == S_OK, "loadXML failed\n");
4385     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4386
4387     r = IXMLDOMDocument_get_documentElement( doc, &element );
4388     ok( r == S_OK, "ret %08x\n", r);
4389
4390     r = IXMLDOMElement_get_childNodes( element, &root_list );
4391     ok( r == S_OK, "ret %08x\n", r);
4392
4393     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4394     ok( r == S_OK, "ret %08x\n", r);
4395
4396     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4397     ok( r == S_OK, "ret %08x\n", r);
4398
4399     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4400     ok( r == S_OK, "ret %08x\n", r);
4401
4402     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4403     ok( r == S_OK, "ret %08x\n", r);
4404
4405     IXMLDOMNodeList_Release( fo_list );
4406
4407     /* invalid parameter: NULL ptr for element to remove */
4408     removed_node = (void*)0xdeadbeef;
4409     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4410     ok( r == E_INVALIDARG, "ret %08x\n", r );
4411     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4412
4413     /* invalid parameter: NULL for replacement element. (Sic!) */
4414     removed_node = (void*)0xdeadbeef;
4415     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4416     ok( r == E_INVALIDARG, "ret %08x\n", r );
4417     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4418
4419     /* invalid parameter: OldNode is not a child */
4420     removed_node = (void*)0xdeadbeef;
4421     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4422     ok( r == E_INVALIDARG, "ret %08x\n", r );
4423     ok( removed_node == NULL, "%p\n", removed_node );
4424     IXMLDOMNode_Release( lc_node );
4425
4426     /* invalid parameter: would create loop */
4427     removed_node = (void*)0xdeadbeef;
4428     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4429     ok( r == E_FAIL, "ret %08x\n", r );
4430     ok( removed_node == NULL, "%p\n", removed_node );
4431
4432     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4433     ok( r == S_OK, "ret %08x\n", r );
4434
4435     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4436     ok( r == S_OK, "ret %08x\n", r );
4437
4438     /* ba_node and temp_node refer to the same node, yet they
4439        are different interface pointers */
4440     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4441     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4442     ok( r == S_OK, "ret %08x\n", r );
4443     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4444     ok( r == S_OK, "ret %08x\n", r );
4445     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4446
4447     IUnknown_Release( unk1 );
4448     IUnknown_Release( unk2 );
4449
4450     /* ba_node should have been removed from below fo_node */
4451     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4452     ok( r == S_OK, "ret %08x\n", r );
4453
4454     /* MS quirk: replaceChild also accepts elements instead of nodes */
4455     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4456     ok( r == S_OK, "ret %08x\n", r );
4457     EXPECT_REF(ba_element, 2);
4458
4459     removed_node = NULL;
4460     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4461     ok( r == S_OK, "ret %08x\n", r );
4462     ok( removed_node != NULL, "got %p\n", removed_node);
4463     EXPECT_REF(ba_element, 3);
4464     IXMLDOMElement_Release( ba_element );
4465
4466     r = IXMLDOMNodeList_get_length( fo_list, &len);
4467     ok( r == S_OK, "ret %08x\n", r );
4468     ok( len == 0, "len %d\n", len);
4469
4470     IXMLDOMNodeList_Release( fo_list );
4471
4472     IXMLDOMNode_Release(ba_node);
4473     IXMLDOMNode_Release(fo_node);
4474     IXMLDOMNode_Release(temp_node);
4475     IXMLDOMNodeList_Release( root_list );
4476     IXMLDOMElement_Release( element );
4477     IXMLDOMDocument_Release( doc );
4478
4479     free_bstrs();
4480 }
4481
4482 static void test_removeNamedItem(void)
4483 {
4484     IXMLDOMDocument *doc;
4485     IXMLDOMElement *element;
4486     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4487     IXMLDOMNodeList *root_list;
4488     IXMLDOMNamedNodeMap * pr_attrs;
4489     VARIANT_BOOL b;
4490     BSTR str;
4491     LONG len;
4492     HRESULT r;
4493
4494     doc = create_document(&IID_IXMLDOMDocument);
4495     if (!doc) return;
4496
4497     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4498     ok( r == S_OK, "loadXML failed\n");
4499     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4500
4501     r = IXMLDOMDocument_get_documentElement( doc, &element );
4502     ok( r == S_OK, "ret %08x\n", r);
4503
4504     r = IXMLDOMElement_get_childNodes( element, &root_list );
4505     ok( r == S_OK, "ret %08x\n", r);
4506
4507     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4508     ok( r == S_OK, "ret %08x\n", r);
4509
4510     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4511     ok( r == S_OK, "ret %08x\n", r);
4512
4513     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4514     ok( r == S_OK, "ret %08x\n", r);
4515     ok( len == 3, "length %d\n", len);
4516
4517     removed_node = (void*)0xdeadbeef;
4518     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4519     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4520     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4521
4522     removed_node = (void*)0xdeadbeef;
4523     str = SysAllocString(szvr);
4524     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4525     ok ( r == S_OK, "ret %08x\n", r);
4526
4527     removed_node2 = (void*)0xdeadbeef;
4528     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4529     ok ( r == S_FALSE, "ret %08x\n", r);
4530     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4531
4532     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4533     ok( r == S_OK, "ret %08x\n", r);
4534     ok( len == 2, "length %d\n", len);
4535
4536     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4537     ok ( r == S_OK, "ret %08x\n", r);
4538     IXMLDOMNode_Release(removed_node);
4539
4540     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4541     ok( r == S_OK, "ret %08x\n", r);
4542     ok( len == 3, "length %d\n", len);
4543
4544     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4545     ok ( r == S_OK, "ret %08x\n", r);
4546
4547     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4548     ok( r == S_OK, "ret %08x\n", r);
4549     ok( len == 2, "length %d\n", len);
4550
4551     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4552     ok ( r == S_FALSE, "ret %08x\n", r);
4553
4554     SysFreeString(str);
4555
4556     IXMLDOMNamedNodeMap_Release( pr_attrs );
4557     IXMLDOMNode_Release( pr_node );
4558     IXMLDOMNodeList_Release( root_list );
4559     IXMLDOMElement_Release( element );
4560     IXMLDOMDocument_Release( doc );
4561
4562     free_bstrs();
4563 }
4564
4565 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4566 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4567                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4568                                     DWORD expected2)
4569 {
4570     DWORD enabled, supported;
4571     HRESULT hr;
4572
4573     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4574     if (result == result2)
4575         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4576     else
4577         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4578            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4579
4580     supported = enabled = 0xCAFECAFE;
4581     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4582     ok(hr == S_OK, "ret %08x\n", hr );
4583     if (expected == expected2)
4584         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4585     else
4586         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4587            "Expected %08x, got %08x\n", expected2, enabled);
4588
4589     /* reset the safety options */
4590
4591     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4592             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4593             0);
4594     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4595
4596     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4597     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4598     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4599 }
4600
4601 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4602 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4603 {
4604     DWORD enabled = 0, supported = 0;
4605     HRESULT hr;
4606
4607     /* get */
4608     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4609     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4610     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4611     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4612
4613     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4614     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4615     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4616        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4617         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4618              "got %08x\n", supported);
4619     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4620
4621     /* set -- individual flags */
4622
4623     test_IObjectSafety_set(safety, S_OK, S_OK,
4624         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4625         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4626
4627     test_IObjectSafety_set(safety, S_OK, S_OK,
4628         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4629         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4630
4631     test_IObjectSafety_set(safety, S_OK, S_OK,
4632         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4633         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4634
4635     /* set INTERFACE_USES_DISPEX  */
4636
4637     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4638         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4639         0, 0);
4640
4641     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4642         INTERFACE_USES_DISPEX, 0,
4643         0, 0);
4644
4645     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4646         0, INTERFACE_USES_DISPEX,
4647         0, 0);
4648
4649     /* set option masking */
4650
4651     test_IObjectSafety_set(safety, S_OK, S_OK,
4652         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4653         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4654         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4655         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4656
4657     test_IObjectSafety_set(safety, S_OK, S_OK,
4658         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4659         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4660         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4661         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4662
4663     test_IObjectSafety_set(safety, S_OK, S_OK,
4664         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4665         INTERFACE_USES_SECURITY_MANAGER,
4666         0,
4667         0);
4668
4669     /* set -- inheriting previous settings */
4670
4671     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4672                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4673                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4674     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4675     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4676     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4677     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4678     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4679        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4680         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4681              "got %08x\n", supported);
4682
4683     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4684                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4685                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4686     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4687     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4688     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4689     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4690                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4691                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4692     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4693        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4694         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4695              "got %08x\n", supported);
4696 }
4697
4698 static void test_XMLHTTP(void)
4699 {
4700     static const char bodyA[] = "mode=Test";
4701     static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
4702     static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
4703     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4704     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4705
4706     IXMLHttpRequest *xhr;
4707     IObjectSafety *safety;
4708     IObjectWithSite *obj_site, *obj_site2;
4709     BSTR bstrResponse, str, str1;
4710     VARIANT varbody, varbody_ref;
4711     VARIANT dummy;
4712     VARIANT async;
4713     LONG state, status, bound;
4714     IDispatch *event;
4715     void *ptr;
4716     HRESULT hr;
4717     HGLOBAL g;
4718
4719     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4720         &IID_IXMLHttpRequest, (void**)&xhr);
4721     if (FAILED(hr))
4722     {
4723         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4724         return;
4725     }
4726
4727     VariantInit(&dummy);
4728     V_VT(&dummy) = VT_ERROR;
4729     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4730     VariantInit(&async);
4731     V_VT(&async) = VT_BOOL;
4732     V_BOOL(&async) = VARIANT_FALSE;
4733
4734     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4735     EXPECT_HR(hr, S_OK);
4736
4737     hr = IXMLHttpRequest_abort(xhr);
4738     EXPECT_HR(hr, S_OK);
4739
4740     V_VT(&varbody) = VT_I2;
4741     V_I2(&varbody) = 1;
4742     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4743     EXPECT_HR(hr, E_PENDING);
4744     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4745     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4746
4747     V_VT(&varbody) = VT_I2;
4748     V_I2(&varbody) = 1;
4749     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4750     EXPECT_HR(hr, E_PENDING);
4751     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4752     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4753
4754     /* send before open */
4755     hr = IXMLHttpRequest_send(xhr, dummy);
4756     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4757
4758     /* initial status code */
4759     hr = IXMLHttpRequest_get_status(xhr, NULL);
4760     EXPECT_HR(hr, E_INVALIDARG);
4761
4762     status = 0xdeadbeef;
4763     hr = IXMLHttpRequest_get_status(xhr, &status);
4764     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4765     ok(status == 0xdeadbeef, "got %d\n", status);
4766
4767     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4768     ok(hr == E_FAIL, "got 0x%08x\n", hr);
4769
4770     /* invalid parameters */
4771     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4772     EXPECT_HR(hr, E_INVALIDARG);
4773
4774     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4775     EXPECT_HR(hr, E_INVALIDARG);
4776
4777     hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
4778     EXPECT_HR(hr, E_INVALIDARG);
4779
4780     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4781     EXPECT_HR(hr, E_INVALIDARG);
4782
4783     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4784     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4785
4786     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4787     EXPECT_HR(hr, E_INVALIDARG);
4788
4789     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4790     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4791
4792     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
4793     EXPECT_HR(hr, E_INVALIDARG);
4794
4795     state = -1;
4796     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4797     EXPECT_HR(hr, S_OK);
4798     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4799
4800     event = create_dispevent();
4801
4802     EXPECT_REF(event, 1);
4803     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
4804     EXPECT_HR(hr, S_OK);
4805     EXPECT_REF(event, 2);
4806
4807     g_unexpectedcall = g_expectedcall = 0;
4808
4809     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4810     EXPECT_HR(hr, S_OK);
4811
4812     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
4813     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
4814
4815     /* status code after ::open() */
4816     status = 0xdeadbeef;
4817     hr = IXMLHttpRequest_get_status(xhr, &status);
4818     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4819     ok(status == 0xdeadbeef, "got %d\n", status);
4820
4821     state = -1;
4822     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4823     EXPECT_HR(hr, S_OK);
4824     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
4825
4826     hr = IXMLHttpRequest_abort(xhr);
4827     EXPECT_HR(hr, S_OK);
4828
4829     state = -1;
4830     hr = IXMLHttpRequest_get_readyState(xhr, &state);
4831     EXPECT_HR(hr, S_OK);
4832     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
4833         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
4834
4835     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4836     EXPECT_HR(hr, S_OK);
4837
4838     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
4839     EXPECT_HR(hr, S_OK);
4840
4841     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
4842     EXPECT_HR(hr, E_INVALIDARG);
4843
4844     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
4845     EXPECT_HR(hr, E_INVALIDARG);
4846
4847     V_VT(&varbody) = VT_BSTR;
4848     V_BSTR(&varbody) = _bstr_(bodyA);
4849
4850     hr = IXMLHttpRequest_send(xhr, varbody);
4851     if (hr == INET_E_RESOURCE_NOT_FOUND)
4852     {
4853         skip("No connection could be made with crossover.codeweavers.com\n");
4854         IXMLHttpRequest_Release(xhr);
4855         return;
4856     }
4857     EXPECT_HR(hr, S_OK);
4858
4859     /* response headers */
4860     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
4861     EXPECT_HR(hr, E_INVALIDARG);
4862     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
4863     EXPECT_HR(hr, S_OK);
4864     /* status line is stripped already */
4865     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
4866     ok(*str, "got empty headers\n");
4867     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
4868     EXPECT_HR(hr, S_OK);
4869     ok(str1 != str, "got %p\n", str1);
4870     SysFreeString(str1);
4871     SysFreeString(str);
4872
4873     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
4874     EXPECT_HR(hr, E_INVALIDARG);
4875     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
4876     EXPECT_HR(hr, E_INVALIDARG);
4877     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
4878     EXPECT_HR(hr, S_OK);
4879     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
4880     SysFreeString(str);
4881
4882     /* status code after ::send() */
4883     status = 0xdeadbeef;
4884     hr = IXMLHttpRequest_get_status(xhr, &status);
4885     EXPECT_HR(hr, S_OK);
4886     ok(status == 200, "got %d\n", status);
4887
4888     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
4889     EXPECT_HR(hr, E_INVALIDARG);
4890
4891     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4892     EXPECT_HR(hr, S_OK);
4893     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
4894     SysFreeString(str);
4895
4896     /* another ::send() after completed request */
4897     V_VT(&varbody) = VT_BSTR;
4898     V_BSTR(&varbody) = _bstr_(bodyA);
4899
4900     hr = IXMLHttpRequest_send(xhr, varbody);
4901     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4902
4903     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4904     EXPECT_HR(hr, S_OK);
4905     /* the server currently returns "FAILED" because the Content-Type header is
4906      * not what the server expects */
4907     if(hr == S_OK)
4908     {
4909         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
4910             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
4911         SysFreeString(bstrResponse);
4912     }
4913
4914     /* POST: VT_VARIANT|VT_BYREF body */
4915     V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
4916     V_VARIANTREF(&varbody_ref) = &varbody;
4917     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
4918     EXPECT_HR(hr, S_OK);
4919     hr = IXMLHttpRequest_send(xhr, varbody_ref);
4920     EXPECT_HR(hr, S_OK);
4921
4922     /* GET request */
4923     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
4924     EXPECT_HR(hr, S_OK);
4925
4926     V_VT(&varbody) = VT_EMPTY;
4927
4928     hr = IXMLHttpRequest_send(xhr, varbody);
4929     if (hr == INET_E_RESOURCE_NOT_FOUND)
4930     {
4931         skip("No connection could be made with crossover.codeweavers.com\n");
4932         IXMLHttpRequest_Release(xhr);
4933         return;
4934     }
4935     EXPECT_HR(hr, S_OK);
4936
4937     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
4938     EXPECT_HR(hr, E_INVALIDARG);
4939
4940     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
4941     EXPECT_HR(hr, S_OK);
4942     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
4943         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
4944     SysFreeString(bstrResponse);
4945
4946     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
4947     EXPECT_HR(hr, E_INVALIDARG);
4948
4949     V_VT(&varbody) = VT_EMPTY;
4950     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4951     EXPECT_HR(hr, S_OK);
4952     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
4953     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
4954
4955     bound = -1;
4956     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
4957     EXPECT_HR(hr, S_OK);
4958     ok(bound == 0, "got %d, expected zero bound\n", bound);
4959
4960     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
4961     EXPECT_HR(hr, S_OK);
4962     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
4963     SafeArrayUnaccessData(V_ARRAY(&varbody));
4964
4965     VariantClear(&varbody);
4966
4967     /* get_responseStream */
4968     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
4969     EXPECT_HR(hr, E_INVALIDARG);
4970
4971     V_VT(&varbody) = VT_EMPTY;
4972     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4973     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
4974     EXPECT_HR(hr, S_OK);
4975     EXPECT_REF(V_UNKNOWN(&varbody), 1);
4976
4977     g = NULL;
4978     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
4979     EXPECT_HR(hr, S_OK);
4980     ok(g != NULL, "got %p\n", g);
4981
4982     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
4983     EXPECT_HR(hr, S_OK);
4984     if(hr == S_OK)
4985     {
4986         test_IObjectSafety_common(safety);
4987         IObjectSafety_Release(safety);
4988     }
4989
4990     IDispatch_Release(event);
4991
4992     /* interaction with object site */
4993     EXPECT_REF(xhr, 1);
4994     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
4995     EXPECT_HR(hr, S_OK);
4996 todo_wine {
4997     EXPECT_REF(xhr, 1);
4998     EXPECT_REF(obj_site, 1);
4999 }
5000
5001     IObjectWithSite_AddRef(obj_site);
5002 todo_wine {
5003     EXPECT_REF(obj_site, 2);
5004     EXPECT_REF(xhr, 1);
5005 }
5006     IObjectWithSite_Release(obj_site);
5007
5008     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
5009     EXPECT_HR(hr, S_OK);
5010 todo_wine {
5011     EXPECT_REF(xhr, 1);
5012     EXPECT_REF(obj_site, 1);
5013     EXPECT_REF(obj_site2, 1);
5014     ok(obj_site != obj_site2, "expected new instance\n");
5015 }
5016     SET_EXPECT(site_qi_IServiceProvider);
5017     SET_EXPECT(sp_queryservice_SID_SBindHost);
5018     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5019     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
5020     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
5021     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
5022
5023     /* calls to IHTMLDocument2 */
5024     SET_EXPECT(htmldoc2_get_all);
5025     SET_EXPECT(collection_get_length);
5026     SET_EXPECT(htmldoc2_get_url);
5027
5028     SET_EXPECT(site_qi_IXMLDOMDocument);
5029     SET_EXPECT(site_qi_IOleClientSite);
5030
5031     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
5032     EXPECT_HR(hr, S_OK);
5033
5034     CHECK_CALLED(site_qi_IServiceProvider);
5035 todo_wine
5036     CHECK_CALLED(sp_queryservice_SID_SBindHost);
5037     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5038 todo_wine {
5039     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
5040     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
5041     /* this one isn't very reliable
5042     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
5043
5044     CHECK_CALLED(htmldoc2_get_all);
5045     CHECK_CALLED(collection_get_length);
5046     CHECK_CALLED(htmldoc2_get_url);
5047
5048     CHECK_CALLED(site_qi_IXMLDOMDocument);
5049     CHECK_CALLED(site_qi_IOleClientSite);
5050 }
5051     IObjectWithSite_Release(obj_site);
5052
5053     /* try to set site another time */
5054
5055     /* to be removed once IObjectWithSite is properly separated */
5056     SET_EXPECT(site_qi_IServiceProvider);
5057     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5058
5059     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5060     EXPECT_HR(hr, S_OK);
5061
5062     todo_wine EXPECT_REF(xhr, 1);
5063     IXMLHttpRequest_Release(xhr);
5064
5065     /* still works after request is released */
5066
5067     /* to be removed once IObjectWithSite is properly separated */
5068     SET_EXPECT(site_qi_IServiceProvider);
5069     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5070
5071     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5072     EXPECT_HR(hr, S_OK);
5073     IObjectWithSite_Release(obj_site2);
5074
5075     free_bstrs();
5076 }
5077
5078 static void test_IXMLDOMDocument2(void)
5079 {
5080     static const WCHAR emptyW[] = {0};
5081     IXMLDOMDocument2 *doc2, *dtddoc2;
5082     IXMLDOMDocument *doc;
5083     IXMLDOMParseError* err;
5084     IDispatchEx *dispex;
5085     VARIANT_BOOL b;
5086     VARIANT var;
5087     HRESULT r;
5088     LONG res;
5089
5090     doc = create_document(&IID_IXMLDOMDocument);
5091     if (!doc) return;
5092
5093     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
5094     if (!dtddoc2)
5095     {
5096         IXMLDOMDocument_Release(doc);
5097         return;
5098     }
5099
5100     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
5101     ok( r == S_OK, "ret %08x\n", r );
5102     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
5103
5104     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
5105     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
5106     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5107
5108     err = NULL;
5109     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
5110     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5111     ok(err != NULL, "expected a pointer\n");
5112     if (err)
5113     {
5114         res = 0;
5115         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5116         /* XML_E_NOTWF */
5117         ok(res == E_XML_NOTWF, "got %08x\n", res);
5118         IXMLDOMParseError_Release(err);
5119     }
5120
5121     r = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
5122     ok( r == S_OK, "loadXML failed\n");
5123     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5124
5125     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
5126     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5127
5128     err = NULL;
5129     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5130     ok(err != NULL, "expected a pointer\n");
5131     if (err)
5132     {
5133         res = 0;
5134         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5135         /* XML_E_NODTD */
5136         ok(res == E_XML_NODTD, "got %08x\n", res);
5137         IXMLDOMParseError_Release(err);
5138     }
5139
5140     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5141     ok( r == S_OK, "ret %08x\n", r );
5142     if(r == S_OK)
5143     {
5144         IDispatchEx_Release(dispex);
5145     }
5146
5147     /* we will check if the variant got cleared */
5148     IXMLDOMDocument2_AddRef(doc2);
5149     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5150
5151     V_VT(&var) = VT_UNKNOWN;
5152     V_UNKNOWN(&var) = (IUnknown *)doc2;
5153
5154     /* invalid calls */
5155     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5156     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5157     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5158
5159     /* valid call */
5160     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5161     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5162     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5163     V_VT(&var) = VT_R4;
5164
5165     /* the variant didn't get cleared*/
5166     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5167
5168     /* setProperty tests */
5169     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5170     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5171     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5172     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5173     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5174     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5175
5176     V_VT(&var) = VT_BSTR;
5177     V_BSTR(&var) = SysAllocString(emptyW);
5178     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5179     ok(r == S_OK, "got 0x%08x\n", r);
5180     VariantClear(&var);
5181
5182     V_VT(&var) = VT_I2;
5183     V_I2(&var) = 0;
5184     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5185     ok(r == E_FAIL, "got 0x%08x\n", r);
5186
5187     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5188     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5189     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5190     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5191
5192     IXMLDOMDocument2_Release( doc2 );
5193     IXMLDOMDocument_Release( doc );
5194
5195     /* DTD validation */
5196     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5197     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5198     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5199     err = NULL;
5200     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5201     ok(err != NULL, "expected pointer\n");
5202     if (err)
5203     {
5204         res = 0;
5205         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5206         ok(res == 0, "got %08x\n", res);
5207         IXMLDOMParseError_Release(err);
5208     }
5209
5210     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5211     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5212     err = NULL;
5213     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5214     ok(err != NULL, "expected pointer\n");
5215     if (err)
5216     {
5217         res = 0;
5218         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5219         /* XML_ELEMENT_UNDECLARED */
5220         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5221         IXMLDOMParseError_Release(err);
5222     }
5223
5224     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5225     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5226     err = NULL;
5227     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5228     ok(err != NULL, "expected pointer\n");
5229     if (err)
5230     {
5231         res = 0;
5232         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5233         /* XML_ELEMENT_ID_NOT_FOUND */
5234         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5235         IXMLDOMParseError_Release(err);
5236     }
5237
5238     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5239     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5240     err = NULL;
5241     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5242     ok(err != NULL, "expected pointer\n");
5243     if (err)
5244     {
5245         res = 0;
5246         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5247         /* XML_EMPTY_NOT_ALLOWED */
5248         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5249         IXMLDOMParseError_Release(err);
5250     }
5251
5252     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5253     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5254     err = NULL;
5255     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5256     ok(err != NULL, "expected pointer\n");
5257     if (err)
5258     {
5259         res = 0;
5260         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5261         /* XML_ROOT_NAME_MISMATCH */
5262         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5263         IXMLDOMParseError_Release(err);
5264     }
5265
5266     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5267     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5268     err = NULL;
5269     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5270     ok(err != NULL, "expected pointer\n");
5271     if (err)
5272     {
5273         res = 0;
5274         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5275         /* XML_INVALID_CONTENT */
5276         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5277         IXMLDOMParseError_Release(err);
5278     }
5279
5280     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5281     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5282     err = NULL;
5283     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5284     ok(err != NULL, "expected pointer\n");
5285     if (err)
5286     {
5287         res = 0;
5288         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5289         /* XML_ATTRIBUTE_NOT_DEFINED */
5290         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5291         IXMLDOMParseError_Release(err);
5292     }
5293
5294     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5295     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5296     err = NULL;
5297     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5298     ok(err != NULL, "expected pointer\n");
5299     if (err)
5300     {
5301         res = 0;
5302         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5303         /* XML_ATTRIBUTE_FIXED */
5304         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5305         IXMLDOMParseError_Release(err);
5306     }
5307
5308     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5309     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5310     err = NULL;
5311     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5312     ok(err != NULL, "expected pointer\n");
5313     if (err)
5314     {
5315         res = 0;
5316         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5317         /* XML_ATTRIBUTE_VALUE */
5318         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5319         IXMLDOMParseError_Release(err);
5320     }
5321
5322     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5323     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5324     err = NULL;
5325     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5326     ok(err != NULL, "expected pointer\n");
5327     if (err)
5328     {
5329         res = 0;
5330         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5331         /* XML_ILLEGAL_TEXT */
5332         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5333         IXMLDOMParseError_Release(err);
5334     }
5335
5336     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5337     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5338     err = NULL;
5339     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5340     ok(err != NULL, "expected pointer\n");
5341     if (err)
5342     {
5343         res = 0;
5344         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5345         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5346         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5347         IXMLDOMParseError_Release(err);
5348     }
5349
5350     IXMLDOMDocument2_Release( dtddoc2 );
5351     free_bstrs();
5352 }
5353
5354 #define helper_ole_check(expr) { \
5355     HRESULT r = expr; \
5356     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5357 }
5358
5359 #define helper_expect_list_and_release(list, expstr) { \
5360     char *str = list_to_string(list); \
5361     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5362     if (list) IXMLDOMNodeList_Release(list); \
5363 }
5364
5365 #define helper_expect_bstr_and_release(bstr, str) { \
5366     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5367        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5368     SysFreeString(bstr); \
5369 }
5370
5371 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5372 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5373 {
5374     IXMLDOMNode *node1, *node2;
5375     IXMLDOMNodeList *list;
5376     BSTR bstr;
5377
5378     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5379     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5380     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5381     helper_ole_check(IXMLDOMNodeList_reset(list));
5382     helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
5383
5384     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5385     helper_expect_list_and_release(list, "T1.E1.E5.E1.E2.D1 E2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 T4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1");
5386     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5387     if (str)
5388     {
5389         helper_expect_bstr_and_release(bstr, str);
5390     }
5391     else
5392     {
5393         helper_expect_bstr_and_release(bstr, "This is a description.");
5394     }
5395     IXMLDOMNode_Release(node1);
5396
5397     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5398     helper_expect_list_and_release(list, "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
5399     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5400     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5401     IXMLDOMNode_Release(node2);
5402 }
5403
5404 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5405 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5406 {
5407     IXMLDOMNode *node1, *node2;
5408     IXMLDOMNodeList *list;
5409     BSTR bstr;
5410
5411     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5412     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5413     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5414     helper_ole_check(IXMLDOMNodeList_reset(list));
5415     helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
5416
5417     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5418     helper_expect_list_and_release(list, "T1.E2.E10.E2.E2.D1 E2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 T7.E2.E10.E2.E2.D1");
5419     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5420     if (str)
5421     {
5422         helper_expect_bstr_and_release(bstr, str);
5423     }
5424     else
5425     {
5426         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5427     }
5428     IXMLDOMNode_Release(node1);
5429
5430     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5431     helper_expect_list_and_release(list, "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
5432     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5433     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5434     IXMLDOMNode_Release(node2);
5435 }
5436
5437 static void test_whitespace(void)
5438 {
5439     VARIANT_BOOL b;
5440     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5441
5442     doc1 = create_document(&IID_IXMLDOMDocument2);
5443     doc2 = create_document(&IID_IXMLDOMDocument2);
5444     if (!doc1 || !doc2) return;
5445
5446     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5447     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5448     ok(b == VARIANT_FALSE, "expected false\n");
5449     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5450     ok(b == VARIANT_TRUE, "expected true\n");
5451
5452     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5453     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5454     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5455     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5456
5457     /* switch to XPath */
5458     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5459     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5460
5461     check_ws_ignored(doc1, NULL);
5462     check_ws_preserved(doc2, NULL);
5463
5464     /* new instances copy the property */
5465     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5466     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5467
5468     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5469     ok(b == VARIANT_FALSE, "expected false\n");
5470     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5471     ok(b == VARIANT_TRUE, "expected true\n");
5472
5473     check_ws_ignored(doc3, NULL);
5474     check_ws_preserved(doc4, NULL);
5475
5476     /* setting after loading xml affects trimming of leading/trailing ws only */
5477     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5478     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5479
5480     /* the trailing "\n            " isn't there, because it was ws-only node */
5481     check_ws_ignored(doc1, "\n                This is a description. ");
5482     check_ws_preserved(doc2, "This is a description.");
5483
5484     /* it takes effect on reload */
5485     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5486     ok(b == VARIANT_TRUE, "expected true\n");
5487     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5488     ok(b == VARIANT_FALSE, "expected false\n");
5489
5490     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5491     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5492     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5493     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5494
5495     check_ws_preserved(doc1, NULL);
5496     check_ws_ignored(doc2, NULL);
5497
5498     /* other instances follow suit */
5499     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5500     ok(b == VARIANT_TRUE, "expected true\n");
5501     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5502     ok(b == VARIANT_FALSE, "expected false\n");
5503
5504     check_ws_preserved(doc3, NULL);
5505     check_ws_ignored(doc4, NULL);
5506
5507     IXMLDOMDocument_Release(doc1);
5508     IXMLDOMDocument_Release(doc2);
5509     IXMLDOMDocument_Release(doc3);
5510     IXMLDOMDocument_Release(doc4);
5511     free_bstrs();
5512 }
5513
5514 typedef struct {
5515     const GUID *clsid;
5516     const char *name;
5517     const char *ns;
5518     HRESULT hr;
5519 } selection_ns_t;
5520
5521 /* supposed to be tested with szExampleXML */
5522 static const selection_ns_t selection_ns_data[] = {
5523     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5524     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5525     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5526
5527     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5528     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5529     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5530
5531     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5532     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5533     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5534
5535     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5536     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5537     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5538
5539     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5540     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5541     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5542
5543     { NULL }
5544 };
5545
5546 static void test_XPath(void)
5547 {
5548     const selection_ns_t *ptr = selection_ns_data;
5549     VARIANT var;
5550     VARIANT_BOOL b;
5551     IXMLDOMDocument2 *doc;
5552     IXMLDOMDocument *doc2;
5553     IXMLDOMNode *rootNode;
5554     IXMLDOMNode *elem1Node;
5555     IXMLDOMNode *node;
5556     IXMLDOMNodeList *list;
5557     IXMLDOMElement *elem;
5558     IXMLDOMAttribute *attr;
5559     DOMNodeType type;
5560     HRESULT hr;
5561     LONG len;
5562     BSTR str;
5563
5564     doc = create_document(&IID_IXMLDOMDocument2);
5565     if (!doc) return;
5566
5567     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5568     EXPECT_HR(hr, S_OK);
5569     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5570
5571     /* switch to XPath */
5572     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5573
5574     /* some simple queries*/
5575     EXPECT_REF(doc, 1);
5576     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5577     EXPECT_HR(hr, S_OK);
5578     EXPECT_REF(doc, 1);
5579     EXPECT_LIST_LEN(list, 1);
5580
5581     EXPECT_REF(list, 1);
5582     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5583     EXPECT_HR(hr, S_OK);
5584     EXPECT_REF(list, 1);
5585     EXPECT_REF(rootNode, 1);
5586
5587     hr = IXMLDOMNodeList_reset(list);
5588     EXPECT_HR(hr, S_OK);
5589     expect_list_and_release(list, "E2.D1");
5590
5591 if (0)
5592 {
5593     /* namespace:: axis test is disabled until namespace definitions
5594        are supported as attribute nodes, currently it's another node type */
5595     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5596     EXPECT_HR(hr, S_OK);
5597     len = -1;
5598     hr = IXMLDOMNodeList_get_length(list, &len);
5599     EXPECT_HR(hr, S_OK);
5600     ok(len == 2, "got %d\n", len);
5601
5602     hr = IXMLDOMNodeList_nextNode(list, &node);
5603     EXPECT_HR(hr, S_OK);
5604     type = NODE_INVALID;
5605     hr = IXMLDOMNode_get_nodeType(node, &type);
5606     EXPECT_HR(hr, S_OK);
5607     ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5608     IXMLDOMNode_Release(node);
5609
5610     IXMLDOMNodeList_Release(list);
5611 }
5612
5613     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5614     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5615
5616     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5617     expect_list_and_release(list, "E3.E2.E2.D1");
5618
5619     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5620     /* using get_item for query results advances the position */
5621     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5622     expect_node(node, "E2.E2.D1");
5623     IXMLDOMNode_Release(node);
5624     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5625     expect_node(node, "E4.E2.D1");
5626     IXMLDOMNode_Release(node);
5627     ole_check(IXMLDOMNodeList_reset(list));
5628     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5629
5630     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5631     expect_list_and_release(list, "E2.D1");
5632
5633     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5634     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5635     ole_check(IXMLDOMNodeList_reset(list));
5636     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5637
5638     /* select an attribute */
5639     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5640     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5641
5642     /* would evaluate to a number */
5643     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5644     /* would evaluate to a boolean */
5645     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5646     /* would evaluate to a string */
5647     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5648
5649     /* no results */
5650     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5651     expect_list_and_release(list, "");
5652     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
5653     expect_list_and_release(list, "");
5654     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
5655     expect_list_and_release(list, "");
5656     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5657     expect_list_and_release(list, "");
5658
5659     /* foo undeclared in document node */
5660     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5661     /* undeclared in <root> node */
5662     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5663     /* undeclared in <elem> node */
5664     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5665     /* but this trick can be used */
5666     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5667     expect_list_and_release(list, "E3.E4.E2.D1");
5668
5669     /* it has to be declared in SelectionNamespaces */
5670     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5671         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5672
5673     /* now the namespace can be used */
5674     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5675     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5676     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5677     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5678     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5679     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5680     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5681     expect_list_and_release(list, "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
5682
5683     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5684     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5685         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5686
5687     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5688
5689     VariantInit(&var);
5690     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5691     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5692     if (V_VT(&var) == VT_BSTR)
5693         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5694
5695     /* extra attributes - same thing*/
5696     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5697         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5698     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5699
5700     IXMLDOMNode_Release(rootNode);
5701     IXMLDOMNode_Release(elem1Node);
5702
5703     /* alter document with already built list */
5704     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5705     EXPECT_HR(hr, S_OK);
5706     EXPECT_LIST_LEN(list, 1);
5707
5708     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5709     EXPECT_HR(hr, S_OK);
5710     EXPECT_REF(rootNode, 1);
5711     EXPECT_REF(doc, 1);
5712
5713     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5714     EXPECT_HR(hr, S_OK);
5715     IXMLDOMNode_Release(rootNode);
5716
5717     EXPECT_LIST_LEN(list, 1);
5718
5719     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5720     EXPECT_HR(hr, S_OK);
5721     EXPECT_REF(rootNode, 1);
5722
5723     IXMLDOMNodeList_Release(list);
5724
5725     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5726     EXPECT_HR(hr, S_OK);
5727     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5728     SysFreeString(str);
5729     IXMLDOMNode_Release(rootNode);
5730
5731     /* alter node from list and get it another time */
5732     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5733     EXPECT_HR(hr, S_OK);
5734     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5735
5736     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5737     EXPECT_HR(hr, S_OK);
5738     EXPECT_LIST_LEN(list, 1);
5739
5740     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5741     EXPECT_HR(hr, S_OK);
5742
5743     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5744     EXPECT_HR(hr, S_OK);
5745
5746     V_VT(&var) = VT_I2;
5747     V_I2(&var) = 1;
5748     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5749     EXPECT_HR(hr, S_OK);
5750     IXMLDOMElement_Release(elem);
5751     IXMLDOMNode_Release(rootNode);
5752
5753     /* now check attribute to be present */
5754     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5755     EXPECT_HR(hr, S_OK);
5756
5757     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5758     EXPECT_HR(hr, S_OK);
5759
5760     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5761     EXPECT_HR(hr, S_OK);
5762     IXMLDOMAttribute_Release(attr);
5763
5764     IXMLDOMElement_Release(elem);
5765     IXMLDOMNode_Release(rootNode);
5766
5767     /* and now check for attribute in original document */
5768     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
5769     EXPECT_HR(hr, S_OK);
5770
5771     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5772     EXPECT_HR(hr, S_OK);
5773     IXMLDOMAttribute_Release(attr);
5774
5775     IXMLDOMElement_Release(elem);
5776
5777     /* attach node from list to another document */
5778     doc2 = create_document(&IID_IXMLDOMDocument);
5779
5780     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5781     EXPECT_HR(hr, S_OK);
5782     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5783
5784     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5785     EXPECT_HR(hr, S_OK);
5786     EXPECT_LIST_LEN(list, 1);
5787
5788     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5789     EXPECT_HR(hr, S_OK);
5790     EXPECT_REF(rootNode, 1);
5791
5792     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5793     EXPECT_HR(hr, S_OK);
5794     EXPECT_REF(rootNode, 1);
5795     EXPECT_REF(doc2, 1);
5796     EXPECT_REF(list, 1);
5797
5798     EXPECT_LIST_LEN(list, 1);
5799
5800     IXMLDOMNode_Release(rootNode);
5801     IXMLDOMNodeList_Release(list);
5802     IXMLDOMDocument_Release(doc2);
5803     IXMLDOMDocument2_Release(doc);
5804
5805     while (ptr->clsid)
5806     {
5807         hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5808         if (hr != S_OK)
5809         {
5810             win_skip("can't create instance of %s\n", ptr->name);
5811             ptr++;
5812             continue;
5813         }
5814
5815         hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5816         EXPECT_HR(hr, S_OK);
5817         ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5818
5819         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5820         EXPECT_HR(hr, S_OK);
5821
5822         V_VT(&var) = VT_BSTR;
5823         V_BSTR(&var) = _bstr_(ptr->ns);
5824
5825         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5826         ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5827
5828         V_VT(&var) = VT_EMPTY;
5829         hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5830         EXPECT_HR(hr, S_OK);
5831         ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5832         ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5833         VariantClear(&var);
5834
5835         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5836         EXPECT_HR(hr, S_OK);
5837         if (hr == S_OK)
5838             expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5839
5840         IXMLDOMDocument2_Release(doc);
5841         ptr++;
5842     }
5843
5844     free_bstrs();
5845 }
5846
5847 static void test_cloneNode(void )
5848 {
5849     IXMLDOMDocument *doc, *doc2;
5850     VARIANT_BOOL b;
5851     IXMLDOMNodeList *pList;
5852     IXMLDOMNamedNodeMap *mapAttr;
5853     LONG length, length1;
5854     LONG attr_cnt, attr_cnt1;
5855     IXMLDOMNode *node;
5856     IXMLDOMNode *node_clone;
5857     IXMLDOMNode *node_first;
5858     HRESULT hr;
5859
5860     doc = create_document(&IID_IXMLDOMDocument);
5861     if (!doc) return;
5862
5863     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
5864     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5865
5866     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5867     ok( hr == S_OK, "ret %08x\n", hr );
5868     ok( node != NULL, "node %p\n", node );
5869
5870     /* Check invalid parameter */
5871     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5872     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5873
5874     /* All Children */
5875     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5876     ok( hr == S_OK, "ret %08x\n", hr );
5877     ok( node_clone != NULL, "node %p\n", node );
5878
5879     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5880     ok( hr == S_OK, "ret %08x\n", hr );
5881     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5882     ok( hr == S_OK, "ret %08x\n", hr );
5883     IXMLDOMDocument_Release(doc2);
5884     IXMLDOMNode_Release(node_first);
5885
5886     hr = IXMLDOMNode_get_childNodes(node, &pList);
5887     ok( hr == S_OK, "ret %08x\n", hr );
5888     length = 0;
5889     hr = IXMLDOMNodeList_get_length(pList, &length);
5890     ok( hr == S_OK, "ret %08x\n", hr );
5891     ok(length == 1, "got %d\n", length);
5892     IXMLDOMNodeList_Release(pList);
5893
5894     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5895     ok( hr == S_OK, "ret %08x\n", hr );
5896     attr_cnt = 0;
5897     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5898     ok( hr == S_OK, "ret %08x\n", hr );
5899     ok(attr_cnt == 3, "got %d\n", attr_cnt);
5900     IXMLDOMNamedNodeMap_Release(mapAttr);
5901
5902     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5903     ok( hr == S_OK, "ret %08x\n", hr );
5904     length1 = 0;
5905     hr = IXMLDOMNodeList_get_length(pList, &length1);
5906     ok(length1 == 1, "got %d\n", length1);
5907     ok( hr == S_OK, "ret %08x\n", hr );
5908     IXMLDOMNodeList_Release(pList);
5909
5910     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5911     ok( hr == S_OK, "ret %08x\n", hr );
5912     attr_cnt1 = 0;
5913     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5914     ok( hr == S_OK, "ret %08x\n", hr );
5915     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5916     IXMLDOMNamedNodeMap_Release(mapAttr);
5917
5918     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5919     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5920     IXMLDOMNode_Release(node_clone);
5921
5922     /* No Children */
5923     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5924     ok( hr == S_OK, "ret %08x\n", hr );
5925     ok( node_clone != NULL, "node %p\n", node );
5926
5927     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5928     ok(hr == S_FALSE, "ret %08x\n", hr );
5929
5930     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5931     ok(hr == S_OK, "ret %08x\n", hr );
5932     hr = IXMLDOMNodeList_get_length(pList, &length1);
5933     ok(hr == S_OK, "ret %08x\n", hr );
5934     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5935     IXMLDOMNodeList_Release(pList);
5936
5937     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5938     ok(hr == S_OK, "ret %08x\n", hr );
5939     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5940     ok(hr == S_OK, "ret %08x\n", hr );
5941     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5942     IXMLDOMNamedNodeMap_Release(mapAttr);
5943
5944     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5945     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5946     IXMLDOMNode_Release(node_clone);
5947
5948     IXMLDOMNode_Release(node);
5949     IXMLDOMDocument_Release(doc);
5950     free_bstrs();
5951 }
5952
5953 static void test_xmlTypes(void)
5954 {
5955     IXMLDOMDocument *doc;
5956     IXMLDOMElement *pRoot;
5957     HRESULT hr;
5958     IXMLDOMComment *pComment;
5959     IXMLDOMElement *pElement;
5960     IXMLDOMAttribute *pAttribute;
5961     IXMLDOMNamedNodeMap *pAttribs;
5962     IXMLDOMCDATASection *pCDataSec;
5963     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5964     IXMLDOMDocumentFragment *pDocFrag = NULL;
5965     IXMLDOMEntityReference *pEntityRef = NULL;
5966     BSTR str;
5967     IXMLDOMNode *pNextChild;
5968     VARIANT v;
5969     LONG len = 0;
5970
5971     doc = create_document(&IID_IXMLDOMDocument);
5972     if (!doc) return;
5973
5974     pNextChild = (void*)0xdeadbeef;
5975     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5976     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5977
5978     pNextChild = (void*)0xdeadbeef;
5979     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5980     ok(hr == S_FALSE, "ret %08x\n", hr );
5981     ok(pNextChild == NULL, "pDocChild not NULL\n");
5982
5983     /* test previous Sibling */
5984     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5985     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5986
5987     pNextChild = (void*)0xdeadbeef;
5988     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5989     ok(hr == S_FALSE, "ret %08x\n", hr );
5990     ok(pNextChild == NULL, "pNextChild not NULL\n");
5991
5992     /* test get_dataType */
5993     V_VT(&v) = VT_EMPTY;
5994     hr = IXMLDOMDocument_get_dataType(doc, &v);
5995     ok(hr == S_FALSE, "ret %08x\n", hr );
5996     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5997     VariantClear(&v);
5998
5999     /* test implementation */
6000     hr = IXMLDOMDocument_get_implementation(doc, NULL);
6001     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6002
6003     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
6004     ok(hr == S_OK, "ret %08x\n", hr );
6005     if(hr == S_OK)
6006     {
6007         VARIANT_BOOL hasFeature = VARIANT_TRUE;
6008         BSTR sEmpty = SysAllocStringLen(NULL, 0);
6009
6010         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
6011         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6012
6013         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
6014         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6015
6016         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6017         ok(hr == S_OK, "ret %08x\n", hr );
6018         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6019
6020         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
6021         ok(hr == S_OK, "ret %08x\n", hr );
6022         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
6023
6024         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
6025         ok(hr == S_OK, "ret %08x\n", hr );
6026         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
6027
6028         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6029         ok(hr == S_OK, "ret %08x\n", hr );
6030         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6031
6032         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
6033         ok(hr == S_OK, "ret %08x\n", hr );
6034         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6035
6036         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
6037         ok(hr == S_OK, "ret %08x\n", hr );
6038         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6039
6040         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
6041         ok(hr == S_OK, "ret %08x\n", hr );
6042         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6043
6044         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
6045         ok(hr == S_OK, "ret %08x\n", hr );
6046         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6047
6048         SysFreeString(sEmpty);
6049         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
6050     }
6051
6052     pRoot = (IXMLDOMElement*)0x1;
6053     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
6054     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6055     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6056
6057     pRoot = (IXMLDOMElement*)0x1;
6058     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
6059     ok(hr == E_FAIL, "ret %08x\n", hr );
6060     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6061
6062     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6063     ok(hr == S_OK, "ret %08x\n", hr );
6064     if(hr == S_OK)
6065     {
6066         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6067         ok(hr == S_OK, "ret %08x\n", hr );
6068         if(hr == S_OK)
6069         {
6070             /* Comment */
6071             str = SysAllocString(szComment);
6072             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
6073             SysFreeString(str);
6074             ok(hr == S_OK, "ret %08x\n", hr );
6075             if(hr == S_OK)
6076             {
6077                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
6078                 ok(hr == S_OK, "ret %08x\n", hr );
6079
6080                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
6081                 ok(hr == S_OK, "ret %08x\n", hr );
6082                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
6083                 SysFreeString(str);
6084
6085                 hr = IXMLDOMComment_get_xml(pComment, &str);
6086                 ok(hr == S_OK, "ret %08x\n", hr );
6087                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
6088                 SysFreeString(str);
6089
6090                 /* put data Tests */
6091                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
6092                 ok(hr == S_OK, "ret %08x\n", hr );
6093
6094                 /* get data Tests */
6095                 hr = IXMLDOMComment_get_data(pComment, &str);
6096                 ok(hr == S_OK, "ret %08x\n", hr );
6097                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
6098                 SysFreeString(str);
6099
6100                 /* Confirm XML text is good */
6101                 hr = IXMLDOMComment_get_xml(pComment, &str);
6102                 ok(hr == S_OK, "ret %08x\n", hr );
6103                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
6104                 SysFreeString(str);
6105
6106                 /* Confirm we get the put_data Text back */
6107                 hr = IXMLDOMComment_get_text(pComment, &str);
6108                 ok(hr == S_OK, "ret %08x\n", hr );
6109                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
6110                 SysFreeString(str);
6111
6112                 /* test length property */
6113                 hr = IXMLDOMComment_get_length(pComment, &len);
6114                 ok(hr == S_OK, "ret %08x\n", hr );
6115                 ok(len == 21, "expected 21 got %d\n", len);
6116
6117                 /* test substringData */
6118                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
6119                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6120
6121                 /* test substringData - Invalid offset */
6122                 str = (BSTR)&szElement;
6123                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
6124                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6125                 ok( str == NULL, "incorrect string\n");
6126
6127                 /* test substringData - Invalid offset */
6128                 str = (BSTR)&szElement;
6129                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
6130                 ok(hr == S_FALSE, "ret %08x\n", hr );
6131                 ok( str == NULL, "incorrect string\n");
6132
6133                 /* test substringData - Invalid size */
6134                 str = (BSTR)&szElement;
6135                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
6136                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6137                 ok( str == NULL, "incorrect string\n");
6138
6139                 /* test substringData - Invalid size */
6140                 str = (BSTR)&szElement;
6141                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
6142                 ok(hr == S_FALSE, "ret %08x\n", hr );
6143                 ok( str == NULL, "incorrect string\n");
6144
6145                 /* test substringData - Start of string */
6146                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
6147                 ok(hr == S_OK, "ret %08x\n", hr );
6148                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6149                 SysFreeString(str);
6150
6151                 /* test substringData - Middle of string */
6152                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
6153                 ok(hr == S_OK, "ret %08x\n", hr );
6154                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6155                 SysFreeString(str);
6156
6157                 /* test substringData - End of string */
6158                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
6159                 ok(hr == S_OK, "ret %08x\n", hr );
6160                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6161                 SysFreeString(str);
6162
6163                 /* test appendData */
6164                 hr = IXMLDOMComment_appendData(pComment, NULL);
6165                 ok(hr == S_OK, "ret %08x\n", hr );
6166
6167                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
6168                 ok(hr == S_OK, "ret %08x\n", hr );
6169
6170                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
6171                 ok(hr == S_OK, "ret %08x\n", hr );
6172
6173                 hr = IXMLDOMComment_get_text(pComment, &str);
6174                 ok(hr == S_OK, "ret %08x\n", hr );
6175                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6176                 SysFreeString(str);
6177
6178                 /* test insertData */
6179                 str = SysAllocStringLen(NULL, 0);
6180                 hr = IXMLDOMComment_insertData(pComment, -1, str);
6181                 ok(hr == S_OK, "ret %08x\n", hr );
6182
6183                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
6184                 ok(hr == S_OK, "ret %08x\n", hr );
6185
6186                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
6187                 ok(hr == S_OK, "ret %08x\n", hr );
6188
6189                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
6190                 ok(hr == S_OK, "ret %08x\n", hr );
6191
6192                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
6193                 ok(hr == S_OK, "ret %08x\n", hr );
6194
6195                 hr = IXMLDOMComment_insertData(pComment, 0, str);
6196                 ok(hr == S_OK, "ret %08x\n", hr );
6197                 SysFreeString(str);
6198
6199                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
6200                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6201
6202                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
6203                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6204
6205                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
6206                 ok(hr == S_OK, "ret %08x\n", hr );
6207
6208                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
6209                 ok(hr == S_OK, "ret %08x\n", hr );
6210
6211                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
6212                 ok(hr == S_OK, "ret %08x\n", hr );
6213
6214                 hr = IXMLDOMComment_get_text(pComment, &str);
6215                 ok(hr == S_OK, "ret %08x\n", hr );
6216                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6217                 SysFreeString(str);
6218
6219                 /* delete data */
6220                 /* invalid arguments */
6221                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6222                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6223
6224                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6225                 ok(hr == S_OK, "ret %08x\n", hr );
6226
6227                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6228                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6229
6230                 hr = IXMLDOMComment_get_length(pComment, &len);
6231                 ok(hr == S_OK, "ret %08x\n", hr );
6232                 ok(len == 43, "expected 43 got %d\n", len);
6233
6234                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6235                 ok(hr == S_OK, "ret %08x\n", hr );
6236
6237                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6238                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6239
6240                 /* delete from start */
6241                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6242                 ok(hr == S_OK, "ret %08x\n", hr );
6243
6244                 hr = IXMLDOMComment_get_length(pComment, &len);
6245                 ok(hr == S_OK, "ret %08x\n", hr );
6246                 ok(len == 38, "expected 38 got %d\n", len);
6247
6248                 hr = IXMLDOMComment_get_text(pComment, &str);
6249                 ok(hr == S_OK, "ret %08x\n", hr );
6250                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6251                 SysFreeString(str);
6252
6253                 /* delete from end */
6254                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6255                 ok(hr == S_OK, "ret %08x\n", hr );
6256
6257                 hr = IXMLDOMComment_get_length(pComment, &len);
6258                 ok(hr == S_OK, "ret %08x\n", hr );
6259                 ok(len == 35, "expected 35 got %d\n", len);
6260
6261                 hr = IXMLDOMComment_get_text(pComment, &str);
6262                 ok(hr == S_OK, "ret %08x\n", hr );
6263                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6264                 SysFreeString(str);
6265
6266                 /* delete from inside */
6267                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6268                 ok(hr == S_OK, "ret %08x\n", hr );
6269
6270                 hr = IXMLDOMComment_get_length(pComment, &len);
6271                 ok(hr == S_OK, "ret %08x\n", hr );
6272                 ok(len == 2, "expected 2 got %d\n", len);
6273
6274                 hr = IXMLDOMComment_get_text(pComment, &str);
6275                 ok(hr == S_OK, "ret %08x\n", hr );
6276                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6277                 SysFreeString(str);
6278
6279                 /* delete whole data ... */
6280                 hr = IXMLDOMComment_get_length(pComment, &len);
6281                 ok(hr == S_OK, "ret %08x\n", hr );
6282
6283                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6284                 ok(hr == S_OK, "ret %08x\n", hr );
6285                 /* ... and try again with empty string */
6286                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6287                 ok(hr == S_OK, "ret %08x\n", hr );
6288
6289                 /* ::replaceData() */
6290                 V_VT(&v) = VT_BSTR;
6291                 V_BSTR(&v) = SysAllocString(szstr1);
6292                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6293                 ok(hr == S_OK, "ret %08x\n", hr );
6294                 VariantClear(&v);
6295
6296                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6297                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6298                 hr = IXMLDOMComment_get_text(pComment, &str);
6299                 ok(hr == S_OK, "ret %08x\n", hr );
6300                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6301                 SysFreeString(str);
6302
6303                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6304                 ok(hr == S_OK, "ret %08x\n", hr );
6305                 hr = IXMLDOMComment_get_text(pComment, &str);
6306                 ok(hr == S_OK, "ret %08x\n", hr );
6307                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6308                 SysFreeString(str);
6309
6310                 /* NULL pointer means delete */
6311                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6312                 ok(hr == S_OK, "ret %08x\n", hr );
6313                 hr = IXMLDOMComment_get_text(pComment, &str);
6314                 ok(hr == S_OK, "ret %08x\n", hr );
6315                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6316                 SysFreeString(str);
6317
6318                 /* empty string means delete */
6319                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6320                 ok(hr == S_OK, "ret %08x\n", hr );
6321                 hr = IXMLDOMComment_get_text(pComment, &str);
6322                 ok(hr == S_OK, "ret %08x\n", hr );
6323                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6324                 SysFreeString(str);
6325
6326                 /* zero count means insert */
6327                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6328                 ok(hr == S_OK, "ret %08x\n", hr );
6329                 hr = IXMLDOMComment_get_text(pComment, &str);
6330                 ok(hr == S_OK, "ret %08x\n", hr );
6331                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6332                 SysFreeString(str);
6333
6334                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6335                 ok(hr == S_OK, "ret %08x\n", hr );
6336
6337                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6338                 ok(hr == S_OK, "ret %08x\n", hr );
6339                 hr = IXMLDOMComment_get_text(pComment, &str);
6340                 ok(hr == S_OK, "ret %08x\n", hr );
6341                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6342                 SysFreeString(str);
6343
6344                 /* nonempty string, count greater than its length */
6345                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6346                 ok(hr == S_OK, "ret %08x\n", hr );
6347                 hr = IXMLDOMComment_get_text(pComment, &str);
6348                 ok(hr == S_OK, "ret %08x\n", hr );
6349                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6350                 SysFreeString(str);
6351
6352                 /* nonempty string, count less than its length */
6353                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6354                 ok(hr == S_OK, "ret %08x\n", hr );
6355                 hr = IXMLDOMComment_get_text(pComment, &str);
6356                 ok(hr == S_OK, "ret %08x\n", hr );
6357                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6358                 SysFreeString(str);
6359
6360                 IXMLDOMComment_Release(pComment);
6361             }
6362
6363             /* Element */
6364             str = SysAllocString(szElement);
6365             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6366             SysFreeString(str);
6367             ok(hr == S_OK, "ret %08x\n", hr );
6368             if(hr == S_OK)
6369             {
6370                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6371                 ok(hr == S_OK, "ret %08x\n", hr );
6372
6373                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6374                 ok(hr == S_OK, "ret %08x\n", hr );
6375                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6376                 SysFreeString(str);
6377
6378                 hr = IXMLDOMElement_get_xml(pElement, &str);
6379                 ok(hr == S_OK, "ret %08x\n", hr );
6380                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6381                 SysFreeString(str);
6382
6383                 /* Attribute */
6384                 pAttribute = (IXMLDOMAttribute*)0x1;
6385                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6386                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6387                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6388
6389                 pAttribute = (IXMLDOMAttribute*)0x1;
6390                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6391                 ok(hr == E_FAIL, "ret %08x\n", hr );
6392                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6393
6394                 str = SysAllocString(szAttribute);
6395                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6396                 SysFreeString(str);
6397                 ok(hr == S_OK, "ret %08x\n", hr );
6398                 if(hr == S_OK)
6399                 {
6400                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6401
6402                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6403                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6404
6405                     pNextChild = (IXMLDOMNode *)0x1;
6406                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6407                     ok(hr == S_FALSE, "ret %08x\n", hr );
6408                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6409
6410                     /* test Previous Sibling*/
6411                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6412                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6413
6414                     pNextChild = (IXMLDOMNode *)0x1;
6415                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6416                     ok(hr == S_FALSE, "ret %08x\n", hr );
6417                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6418
6419                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6420                     ok(hr == E_FAIL, "ret %08x\n", hr );
6421                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6422
6423                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6424                     ok(hr == S_OK, "ret %08x\n", hr );
6425                     if ( hr == S_OK )
6426                     {
6427                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6428                         ok(hr == S_OK, "ret %08x\n", hr );
6429
6430                         IXMLDOMNamedNodeMap_Release(pAttribs);
6431                     }
6432
6433                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6434                     ok(hr == S_OK, "ret %08x\n", hr );
6435                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6436                     SysFreeString(str);
6437
6438                     /* test nodeName */
6439                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6440                     ok(hr == S_OK, "ret %08x\n", hr );
6441                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6442                     SysFreeString(str);
6443
6444                     /* test name property */
6445                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6446                     ok(hr == S_OK, "ret %08x\n", hr );
6447                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6448                     SysFreeString(str);
6449
6450                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6451                     ok(hr == S_OK, "ret %08x\n", hr );
6452                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6453                     SysFreeString(str);
6454
6455                     IXMLDOMAttribute_Release(pAttribute);
6456
6457                     /* Check Element again with the Add Attribute*/
6458                     hr = IXMLDOMElement_get_xml(pElement, &str);
6459                     ok(hr == S_OK, "ret %08x\n", hr );
6460                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6461                     SysFreeString(str);
6462                 }
6463
6464                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6465                 ok(hr == S_OK, "ret %08x\n", hr );
6466
6467                 hr = IXMLDOMElement_get_xml(pElement, &str);
6468                 ok(hr == S_OK, "ret %08x\n", hr );
6469                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6470                 SysFreeString(str);
6471
6472                 /* Test for reversible escaping */
6473                 str = SysAllocString( szStrangeChars );
6474                 hr = IXMLDOMElement_put_text(pElement, str);
6475                 ok(hr == S_OK, "ret %08x\n", hr );
6476                 SysFreeString( str );
6477
6478                 hr = IXMLDOMElement_get_xml(pElement, &str);
6479                 ok(hr == S_OK, "ret %08x\n", hr );
6480                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6481                 SysFreeString(str);
6482
6483                 hr = IXMLDOMElement_get_text(pElement, &str);
6484                 ok(hr == S_OK, "ret %08x\n", hr );
6485                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6486                 SysFreeString(str);
6487
6488                 IXMLDOMElement_Release(pElement);
6489             }
6490
6491             /* CData Section */
6492             str = SysAllocString(szCData);
6493             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6494             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6495
6496             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6497             SysFreeString(str);
6498             ok(hr == S_OK, "ret %08x\n", hr );
6499             if(hr == S_OK)
6500             {
6501                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6502                 VARIANT var;
6503
6504                 VariantInit(&var);
6505
6506                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6507                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6508
6509                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6510                 ok(hr == S_OK, "ret %08x\n", hr );
6511
6512                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6513                 ok(hr == S_OK, "ret %08x\n", hr );
6514                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6515                 SysFreeString(str);
6516
6517                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6518                 ok(hr == S_OK, "ret %08x\n", hr );
6519                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6520                 SysFreeString(str);
6521
6522                 /* test lastChild */
6523                 pNextChild = (IXMLDOMNode*)0x1;
6524                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6525                 ok(hr == S_FALSE, "ret %08x\n", hr );
6526                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6527
6528                 /* put data Tests */
6529                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6530                 ok(hr == S_OK, "ret %08x\n", hr );
6531
6532                 /* Confirm XML text is good */
6533                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6534                 ok(hr == S_OK, "ret %08x\n", hr );
6535                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6536                 SysFreeString(str);
6537
6538                 /* Confirm we get the put_data Text back */
6539                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6540                 ok(hr == S_OK, "ret %08x\n", hr );
6541                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6542                 SysFreeString(str);
6543
6544                 /* test length property */
6545                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6546                 ok(hr == S_OK, "ret %08x\n", hr );
6547                 ok(len == 21, "expected 21 got %d\n", len);
6548
6549                 /* test get data */
6550                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6551                 ok(hr == S_OK, "ret %08x\n", hr );
6552                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6553                 SysFreeString(str);
6554
6555                 /* test substringData */
6556                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6557                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6558
6559                 /* test substringData - Invalid offset */
6560                 str = (BSTR)&szElement;
6561                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6562                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6563                 ok( str == NULL, "incorrect string\n");
6564
6565                 /* test substringData - Invalid offset */
6566                 str = (BSTR)&szElement;
6567                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6568                 ok(hr == S_FALSE, "ret %08x\n", hr );
6569                 ok( str == NULL, "incorrect string\n");
6570
6571                 /* test substringData - Invalid size */
6572                 str = (BSTR)&szElement;
6573                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6574                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6575                 ok( str == NULL, "incorrect string\n");
6576
6577                 /* test substringData - Invalid size */
6578                 str = (BSTR)&szElement;
6579                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6580                 ok(hr == S_FALSE, "ret %08x\n", hr );
6581                 ok( str == NULL, "incorrect string\n");
6582
6583                 /* test substringData - Start of string */
6584                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6585                 ok(hr == S_OK, "ret %08x\n", hr );
6586                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6587                 SysFreeString(str);
6588
6589                 /* test substringData - Middle of string */
6590                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6591                 ok(hr == S_OK, "ret %08x\n", hr );
6592                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6593                 SysFreeString(str);
6594
6595                 /* test substringData - End of string */
6596                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6597                 ok(hr == S_OK, "ret %08x\n", hr );
6598                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6599                 SysFreeString(str);
6600
6601                 /* test appendData */
6602                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6603                 ok(hr == S_OK, "ret %08x\n", hr );
6604
6605                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6606                 ok(hr == S_OK, "ret %08x\n", hr );
6607
6608                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6609                 ok(hr == S_OK, "ret %08x\n", hr );
6610
6611                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6612                 ok(hr == S_OK, "ret %08x\n", hr );
6613                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6614                 SysFreeString(str);
6615
6616                 /* test insertData */
6617                 str = SysAllocStringLen(NULL, 0);
6618                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6619                 ok(hr == S_OK, "ret %08x\n", hr );
6620
6621                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6622                 ok(hr == S_OK, "ret %08x\n", hr );
6623
6624                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6625                 ok(hr == S_OK, "ret %08x\n", hr );
6626
6627                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6628                 ok(hr == S_OK, "ret %08x\n", hr );
6629
6630                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6631                 ok(hr == S_OK, "ret %08x\n", hr );
6632
6633                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6634                 ok(hr == S_OK, "ret %08x\n", hr );
6635                 SysFreeString(str);
6636
6637                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6638                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6639
6640                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6641                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6642
6643                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6644                 ok(hr == S_OK, "ret %08x\n", hr );
6645
6646                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6647                 ok(hr == S_OK, "ret %08x\n", hr );
6648
6649                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6650                 ok(hr == S_OK, "ret %08x\n", hr );
6651
6652                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6653                 ok(hr == S_OK, "ret %08x\n", hr );
6654                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6655                 SysFreeString(str);
6656
6657                 /* delete data */
6658                 /* invalid arguments */
6659                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6660                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6661
6662                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6663                 ok(hr == S_OK, "ret %08x\n", hr );
6664
6665                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6666                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6667
6668                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6669                 ok(hr == S_OK, "ret %08x\n", hr );
6670                 ok(len == 43, "expected 43 got %d\n", len);
6671
6672                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6673                 ok(hr == S_OK, "ret %08x\n", hr );
6674
6675                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6676                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6677
6678                 /* delete from start */
6679                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6680                 ok(hr == S_OK, "ret %08x\n", hr );
6681
6682                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6683                 ok(hr == S_OK, "ret %08x\n", hr );
6684                 ok(len == 38, "expected 38 got %d\n", len);
6685
6686                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6687                 ok(hr == S_OK, "ret %08x\n", hr );
6688                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6689                 SysFreeString(str);
6690
6691                 /* delete from end */
6692                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6693                 ok(hr == S_OK, "ret %08x\n", hr );
6694
6695                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6696                 ok(hr == S_OK, "ret %08x\n", hr );
6697                 ok(len == 35, "expected 35 got %d\n", len);
6698
6699                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6700                 ok(hr == S_OK, "ret %08x\n", hr );
6701                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6702                 SysFreeString(str);
6703
6704                 /* delete from inside */
6705                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6706                 ok(hr == S_OK, "ret %08x\n", hr );
6707
6708                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6709                 ok(hr == S_OK, "ret %08x\n", hr );
6710                 ok(len == 2, "expected 2 got %d\n", len);
6711
6712                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6713                 ok(hr == S_OK, "ret %08x\n", hr );
6714                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6715                 SysFreeString(str);
6716
6717                 /* delete whole data ... */
6718                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6719                 ok(hr == S_OK, "ret %08x\n", hr );
6720
6721                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6722                 ok(hr == S_OK, "ret %08x\n", hr );
6723
6724                 /* ... and try again with empty string */
6725                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6726                 ok(hr == S_OK, "ret %08x\n", hr );
6727
6728                 /* ::replaceData() */
6729                 V_VT(&v) = VT_BSTR;
6730                 V_BSTR(&v) = SysAllocString(szstr1);
6731                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6732                 ok(hr == S_OK, "ret %08x\n", hr );
6733                 VariantClear(&v);
6734
6735                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6736                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6737                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6738                 ok(hr == S_OK, "ret %08x\n", hr );
6739                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6740                 SysFreeString(str);
6741
6742                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6743                 ok(hr == S_OK, "ret %08x\n", hr );
6744                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6745                 ok(hr == S_OK, "ret %08x\n", hr );
6746                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6747                 SysFreeString(str);
6748
6749                 /* NULL pointer means delete */
6750                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6751                 ok(hr == S_OK, "ret %08x\n", hr );
6752                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6753                 ok(hr == S_OK, "ret %08x\n", hr );
6754                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6755                 SysFreeString(str);
6756
6757                 /* empty string means delete */
6758                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6759                 ok(hr == S_OK, "ret %08x\n", hr );
6760                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6761                 ok(hr == S_OK, "ret %08x\n", hr );
6762                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6763                 SysFreeString(str);
6764
6765                 /* zero count means insert */
6766                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6767                 ok(hr == S_OK, "ret %08x\n", hr );
6768                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6769                 ok(hr == S_OK, "ret %08x\n", hr );
6770                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6771                 SysFreeString(str);
6772
6773                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6774                 ok(hr == S_OK, "ret %08x\n", hr );
6775
6776                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6777                 ok(hr == S_OK, "ret %08x\n", hr );
6778                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6779                 ok(hr == S_OK, "ret %08x\n", hr );
6780                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6781                 SysFreeString(str);
6782
6783                 /* nonempty string, count greater than its length */
6784                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6785                 ok(hr == S_OK, "ret %08x\n", hr );
6786                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6787                 ok(hr == S_OK, "ret %08x\n", hr );
6788                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6789                 SysFreeString(str);
6790
6791                 /* nonempty string, count less than its length */
6792                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6793                 ok(hr == S_OK, "ret %08x\n", hr );
6794                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6795                 ok(hr == S_OK, "ret %08x\n", hr );
6796                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6797                 SysFreeString(str);
6798
6799                 IXMLDOMCDATASection_Release(pCDataSec);
6800             }
6801
6802             /* Document Fragments */
6803             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6804             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6805
6806             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6807             ok(hr == S_OK, "ret %08x\n", hr );
6808             if(hr == S_OK)
6809             {
6810                 IXMLDOMNode *node;
6811
6812                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6813                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6814
6815                 node = (IXMLDOMNode *)0x1;
6816                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6817                 ok(hr == S_FALSE, "ret %08x\n", hr );
6818                 ok(node == NULL, "expected NULL, got %p\n", node);
6819
6820                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6821                 ok(hr == S_OK, "ret %08x\n", hr );
6822
6823                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6824                 ok(hr == S_OK, "ret %08x\n", hr );
6825                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6826                 SysFreeString(str);
6827
6828                 /* test next Sibling*/
6829                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6830                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6831
6832                 node = (IXMLDOMNode *)0x1;
6833                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6834                 ok(hr == S_FALSE, "ret %08x\n", hr );
6835                 ok(node == NULL, "next sibling not NULL\n");
6836
6837                 /* test Previous Sibling*/
6838                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6839                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6840
6841                 node = (IXMLDOMNode *)0x1;
6842                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6843                 ok(hr == S_FALSE, "ret %08x\n", hr );
6844                 ok(node == NULL, "previous sibling not NULL\n");
6845
6846                 IXMLDOMDocumentFragment_Release(pDocFrag);
6847             }
6848
6849             /* Entity References */
6850             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6851             ok(hr == E_FAIL, "ret %08x\n", hr );
6852             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6853             ok(hr == E_FAIL, "ret %08x\n", hr );
6854
6855             str = SysAllocString(szEntityRef);
6856             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6857             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6858
6859             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6860             SysFreeString(str);
6861             ok(hr == S_OK, "ret %08x\n", hr );
6862             if(hr == S_OK)
6863             {
6864                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6865                 ok(hr == S_OK, "ret %08x\n", hr );
6866
6867                 /* test get_xml*/
6868                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6869                 ok(hr == S_OK, "ret %08x\n", hr );
6870                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6871                 SysFreeString(str);
6872
6873                 IXMLDOMEntityReference_Release(pEntityRef);
6874             }
6875
6876             IXMLDOMElement_Release( pRoot );
6877         }
6878     }
6879
6880     IXMLDOMDocument_Release(doc);
6881
6882     free_bstrs();
6883 }
6884
6885 typedef struct {
6886     const char *name;
6887     const char *type;
6888     HRESULT hr;
6889 } put_datatype_t;
6890
6891 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6892    So many of the names have been changed to reflect this. */
6893 static put_datatype_t put_datatype_data[] = {
6894     { "test_inval",      "abcdefg",     E_FAIL },
6895     { "test_bool",       "Boolean",     S_OK },
6896     { "test_string",     "String",      S_OK },
6897     { "test_number",     "number",      S_OK },
6898     { "test_int",        "InT",         S_OK },
6899     { "test_fixed",      "fixed.14.4",  S_OK },
6900     { "test_datetime",   "DateTime",    S_OK },
6901     { "test_datetimetz", "DateTime.tz", S_OK },
6902     { "test_date",       "Date",        S_OK },
6903     { "test_time",       "Time",        S_OK },
6904     { "test_timetz",     "Time.tz",     S_OK },
6905     { "test_I1",         "I1",          S_OK },
6906     { "test_I2",         "I2",          S_OK },
6907     { "test_I4",         "I4",          S_OK },
6908     { "test_UI1",        "UI1",         S_OK },
6909     { "test_UI2",        "UI2",         S_OK },
6910     { "test_UI4",        "UI4",         S_OK },
6911     { "test_r4",         "r4",          S_OK },
6912     { "test_r8",         "r8",          S_OK },
6913     { "test_float",      "float",       S_OK },
6914     { "test_uuid",       "UuId",        S_OK },
6915     { "test_binhex",     "bin.hex",     S_OK },
6916     { "test_binbase64",  "bin.base64",  S_OK },
6917     { NULL }
6918 };
6919
6920 typedef struct {
6921     DOMNodeType type;
6922     HRESULT hr;
6923 } put_datatype_notype_t;
6924
6925 static put_datatype_notype_t put_dt_notype[] = {
6926     { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6927     { NODE_DOCUMENT_FRAGMENT,      E_FAIL },
6928     { NODE_ENTITY_REFERENCE,       E_FAIL },
6929     { NODE_CDATA_SECTION,          E_FAIL },
6930     { NODE_COMMENT,                E_FAIL },
6931     { NODE_INVALID }
6932 };
6933
6934 static void test_put_dataType( void )
6935 {
6936     const put_datatype_notype_t *ptr2 = put_dt_notype;
6937     const put_datatype_t *ptr = put_datatype_data;
6938     IXMLDOMElement *root, *element;
6939     BSTR nameW, type1W, type2W;
6940     IXMLDOMDocument *doc;
6941     HRESULT hr;
6942
6943     doc = create_document(&IID_IXMLDOMDocument);
6944     if (!doc) return;
6945
6946     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6947     EXPECT_HR(hr, E_INVALIDARG);
6948
6949     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6950     EXPECT_HR(hr, S_OK);
6951
6952     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6953     EXPECT_HR(hr, S_OK);
6954
6955     hr = IXMLDOMElement_put_dataType(root, NULL);
6956     EXPECT_HR(hr, E_INVALIDARG);
6957
6958     while (ptr->name)
6959     {
6960         hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6961         EXPECT_HR(hr, S_OK);
6962         if(hr == S_OK)
6963         {
6964             hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6965             EXPECT_HR(hr, S_OK);
6966
6967             hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6968             ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6969
6970             IXMLDOMElement_Release(element);
6971         }
6972         ptr++;
6973     }
6974
6975     /* check changing types */
6976     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6977     EXPECT_HR(hr, S_OK);
6978
6979     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6980     EXPECT_HR(hr, S_OK);
6981
6982     hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6983     EXPECT_HR(hr, S_OK);
6984
6985     hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6986     EXPECT_HR(hr, S_OK);
6987
6988     IXMLDOMElement_Release(element);
6989
6990     /* try to set type for node without a type */
6991     nameW  = _bstr_("testname");
6992     type1W = _bstr_("string");
6993     type2W = _bstr_("number");
6994     while (ptr2->type != NODE_INVALID)
6995     {
6996         IXMLDOMNode *node;
6997         VARIANT type;
6998
6999         V_VT(&type) = VT_I2;
7000         V_I2(&type) = ptr2->type;
7001
7002         hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
7003         EXPECT_HR(hr, S_OK);
7004         if(hr == S_OK)
7005         {
7006             hr = IXMLDOMElement_appendChild(root, node, NULL);
7007             EXPECT_HR(hr, S_OK);
7008
7009             hr = IXMLDOMNode_put_dataType(node, NULL);
7010             EXPECT_HR(hr, E_INVALIDARG);
7011
7012             hr = IXMLDOMNode_put_dataType(node, type1W);
7013             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7014             hr = IXMLDOMNode_put_dataType(node, type2W);
7015             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7016
7017             IXMLDOMNode_Release(node);
7018         }
7019         ptr2++;
7020     }
7021
7022     IXMLDOMElement_Release(root);
7023     IXMLDOMDocument_Release(doc);
7024     free_bstrs();
7025 }
7026
7027 static void test_save(void)
7028 {
7029     IXMLDOMDocument *doc, *doc2;
7030     IXMLDOMElement *root;
7031     VARIANT file, vDoc;
7032     BSTR sOrig, sNew, filename;
7033     char buffer[100];
7034     DWORD read = 0;
7035     HANDLE hfile;
7036     HRESULT hr;
7037
7038     doc = create_document(&IID_IXMLDOMDocument);
7039     if (!doc) return;
7040
7041     doc2 = create_document(&IID_IXMLDOMDocument);
7042     if (!doc2)
7043     {
7044         IXMLDOMDocument_Release(doc);
7045         return;
7046     }
7047
7048     /* save to IXMLDOMDocument */
7049     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7050     EXPECT_HR(hr, S_OK);
7051
7052     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7053     EXPECT_HR(hr, S_OK);
7054
7055     V_VT(&vDoc) = VT_UNKNOWN;
7056     V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
7057
7058     hr = IXMLDOMDocument_save(doc, vDoc);
7059     EXPECT_HR(hr, S_OK);
7060
7061     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7062     EXPECT_HR(hr, S_OK);
7063
7064     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7065     EXPECT_HR(hr, S_OK);
7066
7067     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7068
7069     SysFreeString(sOrig);
7070     SysFreeString(sNew);
7071
7072     IXMLDOMElement_Release(root);
7073     IXMLDOMDocument_Release(doc2);
7074
7075     /* save to path */
7076     V_VT(&file) = VT_BSTR;
7077     V_BSTR(&file) = _bstr_("test.xml");
7078
7079     hr = IXMLDOMDocument_save(doc, file);
7080     EXPECT_HR(hr, S_OK);
7081
7082     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7083     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7084     if(hfile == INVALID_HANDLE_VALUE) return;
7085
7086     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7087     ok(read != 0, "could not read file\n");
7088     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7089
7090     CloseHandle(hfile);
7091     DeleteFile("test.xml");
7092
7093     /* save to path VT_BSTR | VT_BYREF */
7094     filename = _bstr_("test.xml");
7095     V_VT(&file) = VT_BSTR | VT_BYREF;
7096     V_BSTRREF(&file) = &filename;
7097
7098     hr = IXMLDOMDocument_save(doc, file);
7099     EXPECT_HR(hr, S_OK);
7100
7101     IXMLDOMDocument_Release(doc);
7102
7103     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7104     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7105     if(hfile == INVALID_HANDLE_VALUE) return;
7106
7107     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7108     ok(read != 0, "could not read file\n");
7109     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7110
7111     CloseHandle(hfile);
7112     DeleteFile("test.xml");
7113     free_bstrs();
7114 }
7115
7116 static void test_testTransforms(void)
7117 {
7118     IXMLDOMDocument *doc, *docSS;
7119     IXMLDOMNode *pNode;
7120     VARIANT_BOOL bSucc;
7121
7122     HRESULT hr;
7123
7124     doc = create_document(&IID_IXMLDOMDocument);
7125     if (!doc) return;
7126
7127     docSS = create_document(&IID_IXMLDOMDocument);
7128     if (!docSS)
7129     {
7130         IXMLDOMDocument_Release(doc);
7131         return;
7132     }
7133
7134     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7135     ok(hr == S_OK, "ret %08x\n", hr );
7136
7137     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7138     ok(hr == S_OK, "ret %08x\n", hr );
7139
7140     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7141     ok(hr == S_OK, "ret %08x\n", hr );
7142     if(hr == S_OK)
7143     {
7144         BSTR bOut;
7145
7146         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7147         ok(hr == S_OK, "ret %08x\n", hr );
7148         if(hr == S_OK)
7149         {
7150             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7151             SysFreeString(bOut);
7152         }
7153
7154         IXMLDOMNode_Release(pNode);
7155     }
7156
7157     IXMLDOMDocument_Release(docSS);
7158     IXMLDOMDocument_Release(doc);
7159
7160     free_bstrs();
7161 }
7162
7163 struct namespaces_change_t {
7164     const CLSID *clsid;
7165     const char *name;
7166 };
7167
7168 static const struct namespaces_change_t namespaces_change_test_data[] = {
7169     { &CLSID_DOMDocument,   "CLSID_DOMDocument"   },
7170     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2"  },
7171     { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
7172     { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
7173     { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
7174     { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
7175     { 0 }
7176 };
7177
7178 static void test_namespaces_change(void)
7179 {
7180     const struct namespaces_change_t *class_ptr = namespaces_change_test_data;
7181
7182     while (class_ptr->clsid)
7183     {
7184         IXMLDOMDocument *doc = NULL;
7185         IXMLDOMElement *elem = NULL;
7186         IXMLDOMNode *node = NULL;
7187
7188         VARIANT var;
7189         HRESULT hr;
7190         BSTR str;
7191
7192         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
7193                               &IID_IXMLDOMDocument, (void**)&doc);
7194         if (hr != S_OK)
7195         {
7196             win_skip("failed to create class instance for %s\n", class_ptr->name);
7197             class_ptr++;
7198             continue;
7199         }
7200
7201         V_VT(&var) = VT_I2;
7202         V_I2(&var) = NODE_ELEMENT;
7203
7204         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7205         EXPECT_HR(hr, S_OK);
7206
7207         hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7208         EXPECT_HR(hr, S_OK);
7209
7210         hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7211         EXPECT_HR(hr, S_OK);
7212
7213         /* try same prefix, different uri */
7214         V_VT(&var) = VT_BSTR;
7215         V_BSTR(&var) = _bstr_("ns/uri2");
7216
7217         hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7218         EXPECT_HR(hr, E_INVALIDARG);
7219
7220         /* try same prefix and uri */
7221         V_VT(&var) = VT_BSTR;
7222         V_BSTR(&var) = _bstr_("ns/uri");
7223
7224         hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7225         EXPECT_HR(hr, S_OK);
7226
7227         hr = IXMLDOMElement_get_xml(elem, &str);
7228         EXPECT_HR(hr, S_OK);
7229         ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s for %s\n",
7230            wine_dbgstr_w(str), class_ptr->name);
7231         SysFreeString(str);
7232
7233         IXMLDOMElement_Release(elem);
7234         IXMLDOMDocument_Release(doc);
7235
7236         free_bstrs();
7237
7238         class_ptr++;
7239     }
7240 }
7241
7242 static void test_namespaces_basic(void)
7243 {
7244     static const CHAR namespaces_xmlA[] =
7245         "<?xml version=\"1.0\"?>\n"
7246         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7247         "  <XMI.content>"
7248         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7249         "  </XMI.content>"
7250         "</XMI>";
7251
7252     IXMLDOMDocument *doc;
7253     IXMLDOMElement *elem;
7254     IXMLDOMNode *node;
7255
7256     VARIANT_BOOL b;
7257     HRESULT hr;
7258     BSTR str;
7259
7260     doc = create_document(&IID_IXMLDOMDocument);
7261     if (!doc) return;
7262
7263     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7264     EXPECT_HR(hr, S_OK);
7265     ok(b == VARIANT_TRUE, "got %d\n", b);
7266
7267     str = (BSTR)0xdeadbeef;
7268     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7269     EXPECT_HR(hr, S_FALSE);
7270     ok(str == NULL, "got %p\n", str);
7271
7272     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7273     EXPECT_HR(hr, S_OK);
7274     if(hr == S_OK)
7275     {
7276         IXMLDOMAttribute *attr;
7277         IXMLDOMNode *node2;
7278
7279         hr = IXMLDOMNode_get_firstChild(node, &node2);
7280         EXPECT_HR(hr, S_OK);
7281         ok(node2 != NULL, "got %p\n", node2);
7282
7283         /* Test get_prefix */
7284         hr = IXMLDOMNode_get_prefix(node2, NULL);
7285         EXPECT_HR(hr, E_INVALIDARG);
7286         /* NOTE: Need to test that arg2 gets cleared on Error. */
7287
7288         hr = IXMLDOMNode_get_prefix(node2, &str);
7289         EXPECT_HR(hr, S_OK);
7290         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7291         SysFreeString(str);
7292
7293         hr = IXMLDOMNode_get_nodeName(node2, &str);
7294         EXPECT_HR(hr, S_OK);
7295         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7296         SysFreeString(str);
7297
7298         /* Test get_namespaceURI */
7299         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7300         EXPECT_HR(hr, E_INVALIDARG);
7301         /* NOTE: Need to test that arg2 gets cleared on Error. */
7302
7303         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7304         EXPECT_HR(hr, S_OK);
7305         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7306         SysFreeString(str);
7307
7308         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7309         EXPECT_HR(hr, S_OK);
7310
7311         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7312         EXPECT_HR(hr, S_OK);
7313
7314         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7315         EXPECT_HR(hr, S_OK);
7316         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7317         SysFreeString(str);
7318
7319         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7320         EXPECT_HR(hr, S_OK);
7321         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7322         SysFreeString(str);
7323
7324         IXMLDOMAttribute_Release(attr);
7325         IXMLDOMElement_Release(elem);
7326
7327         IXMLDOMNode_Release(node2);
7328         IXMLDOMNode_Release(node);
7329     }
7330
7331     IXMLDOMDocument_Release(doc);
7332
7333     free_bstrs();
7334 }
7335
7336 static void test_FormattingXML(void)
7337 {
7338     IXMLDOMDocument *doc;
7339     IXMLDOMElement *pElement;
7340     VARIANT_BOOL bSucc;
7341     HRESULT hr;
7342     BSTR str;
7343     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7344     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7345
7346     doc = create_document(&IID_IXMLDOMDocument);
7347     if (!doc) return;
7348
7349     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7350     ok(hr == S_OK, "ret %08x\n", hr );
7351     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7352
7353     if(bSucc == VARIANT_TRUE)
7354     {
7355         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7356         ok(hr == S_OK, "ret %08x\n", hr );
7357         if(hr == S_OK)
7358         {
7359             hr = IXMLDOMElement_get_xml(pElement, &str);
7360             ok(hr == S_OK, "ret %08x\n", hr );
7361             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7362             SysFreeString(str);
7363
7364             IXMLDOMElement_Release(pElement);
7365         }
7366     }
7367
7368     IXMLDOMDocument_Release(doc);
7369
7370     free_bstrs();
7371 }
7372
7373 typedef struct _nodetypedvalue_t {
7374     const char *name;
7375     VARTYPE type;
7376     const char *value; /* value in string format */
7377 } nodetypedvalue_t;
7378
7379 static const nodetypedvalue_t get_nodetypedvalue[] = {
7380     { "root/string",    VT_BSTR, "Wine" },
7381     { "root/string2",   VT_BSTR, "String" },
7382     { "root/number",    VT_BSTR, "12.44" },
7383     { "root/number2",   VT_BSTR, "-3.71e3" },
7384     { "root/int",       VT_I4,   "-13" },
7385     { "root/fixed",     VT_CY,   "7322.9371" },
7386     { "root/bool",      VT_BOOL, "-1" },
7387     { "root/datetime",  VT_DATE, "40135.14" },
7388     { "root/datetimetz",VT_DATE, "37813.59" },
7389     { "root/date",      VT_DATE, "665413" },
7390     { "root/time",      VT_DATE, "0.5813889" },
7391     { "root/timetz",    VT_DATE, "1.112512" },
7392     { "root/i1",        VT_I1,   "-13" },
7393     { "root/i2",        VT_I2,   "31915" },
7394     { "root/i4",        VT_I4,   "-312232" },
7395     { "root/ui1",       VT_UI1,  "123" },
7396     { "root/ui2",       VT_UI2,  "48282" },
7397     { "root/ui4",       VT_UI4,  "949281" },
7398     { "root/r4",        VT_R4,   "213124" },
7399     { "root/r8",        VT_R8,   "0.412" },
7400     { "root/float",     VT_R8,   "41221.421" },
7401     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7402     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7403     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7404     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7405     { 0 }
7406 };
7407
7408 static void test_nodeTypedValue(void)
7409 {
7410     const nodetypedvalue_t *entry = get_nodetypedvalue;
7411     IXMLDOMDocumentType *doctype, *doctype2;
7412     IXMLDOMProcessingInstruction *pi;
7413     IXMLDOMDocumentFragment *frag;
7414     IXMLDOMDocument *doc, *doc2;
7415     IXMLDOMCDATASection *cdata;
7416     IXMLDOMComment *comment;
7417     IXMLDOMNode *node;
7418     VARIANT_BOOL b;
7419     VARIANT value;
7420     HRESULT hr;
7421
7422     doc = create_document(&IID_IXMLDOMDocument);
7423     if (!doc) return;
7424
7425     b = VARIANT_FALSE;
7426     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7427     ok(hr == S_OK, "ret %08x\n", hr );
7428     ok(b == VARIANT_TRUE, "got %d\n", b);
7429
7430     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7431     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7432
7433     V_VT(&value) = VT_BSTR;
7434     V_BSTR(&value) = NULL;
7435     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7436     ok(hr == S_FALSE, "ret %08x\n", hr );
7437     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7438
7439     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7440     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7441
7442     V_VT(&value) = VT_EMPTY;
7443     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7444     ok(hr == S_FALSE, "ret %08x\n", hr );
7445     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7446
7447     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7448     ok(hr == S_OK, "ret %08x\n", hr );
7449
7450     V_VT(&value) = VT_BSTR;
7451     V_BSTR(&value) = NULL;
7452     hr = IXMLDOMNode_get_nodeValue(node, &value);
7453     ok(hr == S_FALSE, "ret %08x\n", hr );
7454     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7455
7456     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7457     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7458
7459     IXMLDOMNode_Release(node);
7460
7461     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7462     ok(hr == S_OK, "ret %08x\n", hr );
7463     {
7464         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7465
7466         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7467         ok(hr == S_OK, "ret %08x\n", hr );
7468         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7469         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7470         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7471             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7472         VariantClear(&value);
7473         IXMLDOMNode_Release(node);
7474     }
7475
7476     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7477     ok(hr == S_OK, "ret %08x\n", hr );
7478     {
7479         V_VT(&value) = VT_NULL;
7480         V_BSTR(&value) = (void*)0xdeadbeef;
7481         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7482         ok(hr == S_OK, "ret %08x\n", hr );
7483         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7484         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7485         IXMLDOMProcessingInstruction_Release(pi);
7486         VariantClear(&value);
7487     }
7488
7489     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7490     ok(hr == S_OK, "ret %08x\n", hr );
7491     {
7492         V_VT(&value) = VT_NULL;
7493         V_BSTR(&value) = (void*)0xdeadbeef;
7494         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7495         ok(hr == S_OK, "ret %08x\n", hr );
7496         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7497         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7498         IXMLDOMCDATASection_Release(cdata);
7499         VariantClear(&value);
7500     }
7501
7502     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7503     ok(hr == S_OK, "ret %08x\n", hr );
7504     {
7505         V_VT(&value) = VT_NULL;
7506         V_BSTR(&value) = (void*)0xdeadbeef;
7507         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7508         ok(hr == S_OK, "ret %08x\n", hr );
7509         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7510         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7511         IXMLDOMComment_Release(comment);
7512         VariantClear(&value);
7513     }
7514
7515     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7516     ok(hr == S_OK, "ret %08x\n", hr );
7517     {
7518         V_VT(&value) = VT_EMPTY;
7519         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7520         ok(hr == S_FALSE, "ret %08x\n", hr );
7521         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7522         IXMLDOMDocumentFragment_Release(frag);
7523     }
7524
7525     doc2 = create_document(&IID_IXMLDOMDocument);
7526
7527     b = VARIANT_FALSE;
7528     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7529     ok(hr == S_OK, "ret %08x\n", hr );
7530     ok(b == VARIANT_TRUE, "got %d\n", b);
7531
7532     EXPECT_REF(doc2, 1);
7533
7534     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7535     ok(hr == S_OK, "ret %08x\n", hr );
7536
7537     EXPECT_REF(doc2, 1);
7538     todo_wine EXPECT_REF(doctype, 2);
7539
7540     {
7541         V_VT(&value) = VT_EMPTY;
7542         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7543         ok(hr == S_FALSE, "ret %08x\n", hr );
7544         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7545     }
7546
7547     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7548     ok(hr == S_OK, "ret %08x\n", hr );
7549     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7550
7551     IXMLDOMDocumentType_Release(doctype2);
7552     IXMLDOMDocumentType_Release(doctype);
7553
7554     IXMLDOMDocument_Release(doc2);
7555
7556     while (entry->name)
7557     {
7558         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7559         ok(hr == S_OK, "ret %08x\n", hr );
7560
7561         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7562         ok(hr == S_OK, "ret %08x\n", hr );
7563         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7564
7565         if (entry->type == (VT_ARRAY|VT_UI1))
7566         {
7567             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7568                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7569         }
7570
7571         if (entry->type != VT_BSTR)
7572         {
7573            if (entry->type == VT_DATE ||
7574                entry->type == VT_R8 ||
7575                entry->type == VT_CY)
7576            {
7577                if (entry->type == VT_DATE)
7578                {
7579                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7580                    ok(hr == S_OK, "ret %08x\n", hr );
7581                }
7582                hr = VariantChangeTypeEx(&value, &value,
7583                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7584                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7585                ok(hr == S_OK, "ret %08x\n", hr );
7586            }
7587            else
7588            {
7589                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7590                ok(hr == S_OK, "ret %08x\n", hr );
7591            }
7592
7593            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7594            if (entry->type == (VT_ARRAY|VT_UI1))
7595            {
7596                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7597                   "expected %s\n", entry->value);
7598            }
7599            else
7600                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7601                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7602         }
7603         else
7604            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7605                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7606
7607         VariantClear( &value );
7608         IXMLDOMNode_Release(node);
7609
7610         entry++;
7611     }
7612
7613     IXMLDOMDocument_Release(doc);
7614     free_bstrs();
7615 }
7616
7617 static void test_TransformWithLoadingLocalFile(void)
7618 {
7619     IXMLDOMDocument *doc;
7620     IXMLDOMDocument *xsl;
7621     IXMLDOMNode *pNode;
7622     VARIANT_BOOL bSucc;
7623     HRESULT hr;
7624     HANDLE file;
7625     DWORD dwWritten;
7626     char lpPathBuffer[MAX_PATH];
7627     int i;
7628
7629     /* Create a Temp File. */
7630     GetTempPathA(MAX_PATH, lpPathBuffer);
7631     strcat(lpPathBuffer, "customers.xml" );
7632
7633     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7634     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7635     if(file == INVALID_HANDLE_VALUE)
7636         return;
7637
7638     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7639     CloseHandle(file);
7640
7641     /* Correct path to not include a escape character. */
7642     for(i=0; i < strlen(lpPathBuffer); i++)
7643     {
7644         if(lpPathBuffer[i] == '\\')
7645             lpPathBuffer[i] = '/';
7646     }
7647
7648     doc = create_document(&IID_IXMLDOMDocument);
7649     if (!doc) return;
7650
7651     xsl = create_document(&IID_IXMLDOMDocument);
7652     if (!xsl)
7653     {
7654         IXMLDOMDocument2_Release(doc);
7655         return;
7656     }
7657
7658     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7659     ok(hr == S_OK, "ret %08x\n", hr );
7660     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7661     if(bSucc == VARIANT_TRUE)
7662     {
7663         BSTR sXSL;
7664         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7665         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7666         BSTR sFileName = _bstr_(lpPathBuffer);
7667         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7668
7669         sXSL = SysAllocStringLen(NULL, nLegnth);
7670         lstrcpyW(sXSL, sPart1);
7671         lstrcatW(sXSL, sFileName);
7672         lstrcatW(sXSL, sPart2);
7673
7674         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7675         ok(hr == S_OK, "ret %08x\n", hr );
7676         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7677         if(bSucc == VARIANT_TRUE)
7678         {
7679             BSTR sResult;
7680
7681             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7682             ok(hr == S_OK, "ret %08x\n", hr );
7683             if(hr == S_OK)
7684             {
7685                 /* This will load the temp file via the XSL */
7686                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7687                 ok(hr == S_OK, "ret %08x\n", hr );
7688                 if(hr == S_OK)
7689                 {
7690                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7691                     SysFreeString(sResult);
7692                 }
7693
7694                 IXMLDOMNode_Release(pNode);
7695             }
7696         }
7697
7698         SysFreeString(sXSL);
7699     }
7700
7701     IXMLDOMDocument_Release(doc);
7702     IXMLDOMDocument_Release(xsl);
7703
7704     DeleteFile(lpPathBuffer);
7705     free_bstrs();
7706 }
7707
7708 static void test_put_nodeValue(void)
7709 {
7710     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7711     IXMLDOMDocument *doc;
7712     IXMLDOMText *text;
7713     IXMLDOMEntityReference *entityref;
7714     IXMLDOMAttribute *attr;
7715     IXMLDOMNode *node;
7716     HRESULT hr;
7717     VARIANT data, type;
7718
7719     doc = create_document(&IID_IXMLDOMDocument);
7720     if (!doc) return;
7721
7722     /* test for unsupported types */
7723     /* NODE_DOCUMENT */
7724     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7725     ok(hr == S_OK, "ret %08x\n", hr );
7726     V_VT(&data) = VT_BSTR;
7727     V_BSTR(&data) = _bstr_("one two three");
7728     hr = IXMLDOMNode_put_nodeValue(node, data);
7729     ok(hr == E_FAIL, "ret %08x\n", hr );
7730     IXMLDOMNode_Release(node);
7731
7732     /* NODE_DOCUMENT_FRAGMENT */
7733     V_VT(&type) = VT_I1;
7734     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7735     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7736     ok(hr == S_OK, "ret %08x\n", hr );
7737     V_VT(&data) = VT_BSTR;
7738     V_BSTR(&data) = _bstr_("one two three");
7739     hr = IXMLDOMNode_put_nodeValue(node, data);
7740     ok(hr == E_FAIL, "ret %08x\n", hr );
7741     IXMLDOMNode_Release(node);
7742
7743     /* NODE_ELEMENT */
7744     V_VT(&type) = VT_I1;
7745     V_I1(&type) = NODE_ELEMENT;
7746     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7747     ok(hr == S_OK, "ret %08x\n", hr );
7748     V_VT(&data) = VT_BSTR;
7749     V_BSTR(&data) = _bstr_("one two three");
7750     hr = IXMLDOMNode_put_nodeValue(node, data);
7751     ok(hr == E_FAIL, "ret %08x\n", hr );
7752     IXMLDOMNode_Release(node);
7753
7754     /* NODE_ENTITY_REFERENCE */
7755     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7756     ok(hr == S_OK, "ret %08x\n", hr );
7757
7758     V_VT(&data) = VT_BSTR;
7759     V_BSTR(&data) = _bstr_("one two three");
7760     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7761     ok(hr == E_FAIL, "ret %08x\n", hr );
7762
7763     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7764     ok(hr == S_OK, "ret %08x\n", hr );
7765     V_VT(&data) = VT_BSTR;
7766     V_BSTR(&data) = _bstr_("one two three");
7767     hr = IXMLDOMNode_put_nodeValue(node, data);
7768     ok(hr == E_FAIL, "ret %08x\n", hr );
7769     IXMLDOMNode_Release(node);
7770     IXMLDOMEntityReference_Release(entityref);
7771
7772     /* supported types */
7773     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7774     ok(hr == S_OK, "ret %08x\n", hr );
7775     V_VT(&data) = VT_BSTR;
7776     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7777     hr = IXMLDOMText_put_nodeValue(text, data);
7778     ok(hr == S_OK, "ret %08x\n", hr );
7779     IXMLDOMText_Release(text);
7780
7781     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7782     ok(hr == S_OK, "ret %08x\n", hr );
7783     V_VT(&data) = VT_BSTR;
7784     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7785     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7786     ok(hr == S_OK, "ret %08x\n", hr );
7787     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7788     ok(hr == S_OK, "ret %08x\n", hr );
7789     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7790         wine_dbgstr_w(V_BSTR(&data)));
7791     VariantClear(&data);
7792     IXMLDOMAttribute_Release(attr);
7793
7794     free_bstrs();
7795
7796     IXMLDOMDocument_Release(doc);
7797 }
7798
7799 static void test_document_IObjectSafety(void)
7800 {
7801     IXMLDOMDocument *doc;
7802     IObjectSafety *safety;
7803     HRESULT hr;
7804
7805     doc = create_document(&IID_IXMLDOMDocument);
7806     if (!doc) return;
7807
7808     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7809     ok(hr == S_OK, "ret %08x\n", hr );
7810
7811     test_IObjectSafety_common(safety);
7812
7813     IObjectSafety_Release(safety);
7814
7815     IXMLDOMDocument_Release(doc);
7816 }
7817
7818 typedef struct _property_test_t {
7819     const GUID *guid;
7820     const char *clsid;
7821     const char *property;
7822     const char *value;
7823 } property_test_t;
7824
7825 static const property_test_t properties_test_data[] = {
7826     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7827     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7828     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7829     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7830     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7831     { 0 }
7832 };
7833
7834 static void test_default_properties(void)
7835 {
7836     const property_test_t *entry = properties_test_data;
7837
7838     while (entry->guid)
7839     {
7840         IXMLDOMDocument2 *doc;
7841         VARIANT var;
7842         HRESULT hr;
7843
7844         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7845         if (hr != S_OK)
7846         {
7847             win_skip("can't create %s instance\n", entry->clsid);
7848             entry++;
7849             continue;
7850         }
7851
7852         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7853         ok(hr == S_OK, "got 0x%08x\n", hr);
7854         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7855            entry->value, entry->clsid);
7856         VariantClear(&var);
7857
7858         IXMLDOMDocument2_Release(doc);
7859
7860         entry++;
7861     }
7862 }
7863
7864 typedef struct {
7865     const char *query;
7866     const char *list;
7867 } xslpattern_test_t;
7868
7869 static const xslpattern_test_t xslpattern_test[] = {
7870     { "root//elem[0]", "E1.E2.D1" },
7871     { "root//elem[index()=1]", "E2.E2.D1" },
7872     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7873     { "root//elem[end()]", "E4.E2.D1" },
7874     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7875     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7876     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7877     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7878     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7879     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7880     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7881     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7882     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7883     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7884     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7885     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7886     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7887     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7888     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7889     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7890     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7891     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7892     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7893     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7894     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7895     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7896     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7897     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7898     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7899     { "root/elem[0]", "E1.E2.D1" },
7900     { "root/elem[index()=1]", "E2.E2.D1" },
7901     { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7902     { "root/elem[end()]", "E4.E2.D1" },
7903     { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7904     { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7905     { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7906     { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7907     { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7908     { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7909     { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7910     { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7911     { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7912     { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7913     { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7914     { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7915     { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7916     { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7917     { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7918     { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7919     { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7920     { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7921     { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7922     { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7923     { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7924     { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7925     { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7926     { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7927     { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7928     { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7929     { NULL }
7930 };
7931
7932 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7933     /* prefixes don't need to be registered, you may use them as they are in the doc */
7934     { "//bar:x", "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7935     /* prefixes must be explicitly specified in the name */
7936     { "//foo:elem", "" },
7937     { "//foo:c", "E3.E4.E2.D1" },
7938     { NULL }
7939 };
7940
7941 static const xslpattern_test_t xslpattern_test_func[] = {
7942     { "attribute()", "" },
7943     { "attribute('depth')", "" },
7944     { "root/attribute('depth')", "A'depth'.E3.D1" },
7945     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7946     { "//x//attribute(id)", NULL },
7947     { "//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" },
7948     { "comment()", "C2.D1" },
7949     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7950     { "element()", "E3.D1" },
7951     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7952     { "//element(a)", NULL },
7953     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7954     { "node()", "P1.D1 C2.D1 E3.D1" },
7955     { "//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" },
7956     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7957     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7958     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7959     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7960     { "pi()", "P1.D1" },
7961     { "//y/pi()", "P1.E4.E3.D1" },
7962     { "root/textnode()", "T2.E3.D1" },
7963     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7964     { NULL }
7965 };
7966
7967 static void test_XSLPattern(void)
7968 {
7969     const xslpattern_test_t *ptr = xslpattern_test;
7970     IXMLDOMDocument2 *doc;
7971     IXMLDOMNodeList *list;
7972     VARIANT_BOOL b;
7973     HRESULT hr;
7974     LONG len;
7975
7976     doc = create_document(&IID_IXMLDOMDocument2);
7977     if (!doc) return;
7978
7979     b = VARIANT_FALSE;
7980     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7981     EXPECT_HR(hr, S_OK);
7982     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7983
7984     /* switch to XSLPattern */
7985     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7986     EXPECT_HR(hr, S_OK);
7987
7988     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7989     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7990     EXPECT_HR(hr, S_OK);
7991
7992     len = 0;
7993     hr = IXMLDOMNodeList_get_length(list, &len);
7994     EXPECT_HR(hr, S_OK);
7995     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7996     ok(len == 3, "expected 3 entries in list, got %d\n", len);
7997     IXMLDOMNodeList_Release(list);
7998
7999     while (ptr->query)
8000     {
8001         list = NULL;
8002         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8003         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8004         len = 0;
8005         hr = IXMLDOMNodeList_get_length(list, &len);
8006         ok(len != 0, "query=%s, empty list\n", ptr->query);
8007         if (len)
8008             expect_list_and_release(list, ptr->list);
8009
8010         ptr++;
8011     }
8012
8013     /* namespace handling */
8014     /* no registered namespaces */
8015     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
8016     EXPECT_HR(hr, S_OK);
8017
8018     ptr = xslpattern_test_no_ns;
8019     while (ptr->query)
8020     {
8021         list = NULL;
8022         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8023         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8024
8025         if (*ptr->list)
8026         {
8027             len = 0;
8028             hr = IXMLDOMNodeList_get_length(list, &len);
8029             EXPECT_HR(hr, S_OK);
8030             ok(len != 0, "query=%s, empty list\n", ptr->query);
8031         }
8032         else
8033         {
8034             len = 1;
8035             hr = IXMLDOMNodeList_get_length(list, &len);
8036             EXPECT_HR(hr, S_OK);
8037             ok(len == 0, "query=%s, empty list\n", ptr->query);
8038         }
8039         if (len)
8040             expect_list_and_release(list, ptr->list);
8041
8042         ptr++;
8043     }
8044
8045     /* explicitly register prefix foo */
8046     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
8047
8048     /* now we get the same behavior as XPath */
8049     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8050     EXPECT_HR(hr, S_OK);
8051     len = 0;
8052     hr = IXMLDOMNodeList_get_length(list, &len);
8053     EXPECT_HR(hr, S_OK);
8054     ok(len != 0, "expected filled list\n");
8055     if (len)
8056         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8057
8058     /* set prefix foo to some nonexistent namespace */
8059     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8060     EXPECT_HR(hr, S_OK);
8061
8062     /* the registered prefix takes precedence */
8063     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8064     EXPECT_HR(hr, S_OK);
8065     len = 0;
8066     hr = IXMLDOMNodeList_get_length(list, &len);
8067     EXPECT_HR(hr, S_OK);
8068     ok(len == 0, "expected empty list\n");
8069     IXMLDOMNodeList_Release(list);
8070
8071     IXMLDOMDocument2_Release(doc);
8072
8073     doc = create_document(&IID_IXMLDOMDocument2);
8074     if (!doc) return;
8075
8076     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8077     EXPECT_HR(hr, S_OK);
8078     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8079
8080     ptr = xslpattern_test_func;
8081     while (ptr->query)
8082     {
8083         list = NULL;
8084         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8085         if (ptr->list)
8086         {
8087             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8088             len = 0;
8089             hr = IXMLDOMNodeList_get_length(list, &len);
8090             if (*ptr->list)
8091             {
8092                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8093                 if (len)
8094                     expect_list_and_release(list, ptr->list);
8095             }
8096             else
8097                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8098         }
8099         else
8100             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8101
8102         ptr++;
8103     }
8104
8105     IXMLDOMDocument2_Release(doc);
8106     free_bstrs();
8107 }
8108
8109 static void test_splitText(void)
8110 {
8111     IXMLDOMCDATASection *cdata;
8112     IXMLDOMElement *root;
8113     IXMLDOMDocument *doc;
8114     IXMLDOMText *text, *text2;
8115     IXMLDOMNode *node;
8116     VARIANT var;
8117     VARIANT_BOOL success;
8118     LONG length;
8119     HRESULT hr;
8120
8121     doc = create_document(&IID_IXMLDOMDocument);
8122     if (!doc) return;
8123
8124     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8125     ok(hr == S_OK, "got 0x%08x\n", hr);
8126
8127     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8128     ok(hr == S_OK, "got 0x%08x\n", hr);
8129
8130     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8131     ok(hr == S_OK, "got 0x%08x\n", hr);
8132
8133     V_VT(&var) = VT_EMPTY;
8134     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8135     ok(hr == S_OK, "got 0x%08x\n", hr);
8136
8137     length = 0;
8138     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8139     ok(hr == S_OK, "got 0x%08x\n", hr);
8140     ok(length > 0, "got %d\n", length);
8141
8142     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8143     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8144
8145     text = (void*)0xdeadbeef;
8146     /* negative offset */
8147     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8148     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8149     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8150
8151     text = (void*)0xdeadbeef;
8152     /* offset outside data */
8153     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8154     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8155     ok(text == 0, "got %p\n", text);
8156
8157     text = (void*)0xdeadbeef;
8158     /* offset outside data */
8159     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8160     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8161     ok(text == 0, "got %p\n", text);
8162
8163     /* no empty node created */
8164     node = (void*)0xdeadbeef;
8165     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8166     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8167     ok(node == 0, "got %p\n", text);
8168
8169     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8170     ok(hr == S_OK, "got 0x%08x\n", hr);
8171
8172     length = 0;
8173     hr = IXMLDOMText_get_length(text, &length);
8174     ok(hr == S_OK, "got 0x%08x\n", hr);
8175     ok(length == 7, "got %d\n", length);
8176
8177     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8178     ok(hr == S_OK, "got 0x%08x\n", hr);
8179     IXMLDOMNode_Release(node);
8180
8181     /* split new text node */
8182     hr = IXMLDOMText_get_length(text, &length);
8183     ok(hr == S_OK, "got 0x%08x\n", hr);
8184
8185     node = (void*)0xdeadbeef;
8186     hr = IXMLDOMText_get_nextSibling(text, &node);
8187     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8188     ok(node == 0, "got %p\n", text);
8189
8190     hr = IXMLDOMText_splitText(text, 0, NULL);
8191     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8192
8193     text2 = (void*)0xdeadbeef;
8194     /* negative offset */
8195     hr = IXMLDOMText_splitText(text, -1, &text2);
8196     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8197     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8198
8199     text2 = (void*)0xdeadbeef;
8200     /* offset outside data */
8201     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8202     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8203     ok(text2 == 0, "got %p\n", text2);
8204
8205     text2 = (void*)0xdeadbeef;
8206     /* offset outside data */
8207     hr = IXMLDOMText_splitText(text, length, &text2);
8208     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8209     ok(text2 == 0, "got %p\n", text);
8210
8211     text2 = 0;
8212     hr = IXMLDOMText_splitText(text, 4, &text2);
8213     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8214     if (text2) IXMLDOMText_Release(text2);
8215
8216     node = 0;
8217     hr = IXMLDOMText_get_nextSibling(text, &node);
8218     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8219     if (node) IXMLDOMNode_Release(node);
8220
8221     IXMLDOMText_Release(text);
8222     IXMLDOMElement_Release(root);
8223     IXMLDOMCDATASection_Release(cdata);
8224     free_bstrs();
8225 }
8226
8227 typedef struct {
8228     const char *name;
8229     const char *uri;
8230     HRESULT hr;
8231 } ns_item_t;
8232
8233 /* default_ns_doc used */
8234 static const ns_item_t qualified_item_tests[] = {
8235     { "xml:lang", NULL, S_FALSE },
8236     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8237     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8238     { "ns:b", NULL, S_FALSE },
8239     { "ns:b", "nshref", S_FALSE },
8240     { "b", "nshref", S_OK },
8241     { "d", NULL, S_OK },
8242     { NULL }
8243 };
8244
8245 static const ns_item_t named_item_tests[] = {
8246     { "xml:lang", NULL, S_OK },
8247     { "lang", NULL, S_FALSE },
8248     { "ns:b", NULL, S_OK },
8249     { "b", NULL, S_FALSE },
8250     { "d", NULL, S_OK },
8251     { NULL }
8252 };
8253
8254 static void test_getQualifiedItem(void)
8255 {
8256     IXMLDOMNode *pr_node, *node;
8257     IXMLDOMNodeList *root_list;
8258     IXMLDOMNamedNodeMap *map;
8259     IXMLDOMElement *element;
8260     const ns_item_t* ptr;
8261     IXMLDOMDocument *doc;
8262     VARIANT_BOOL b;
8263     HRESULT hr;
8264     LONG len;
8265
8266     doc = create_document(&IID_IXMLDOMDocument);
8267     if (!doc) return;
8268
8269     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8270     EXPECT_HR(hr, S_OK);
8271     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8272
8273     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8274     EXPECT_HR(hr, S_OK);
8275
8276     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8277     EXPECT_HR(hr, S_OK);
8278
8279     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8280     EXPECT_HR(hr, S_OK);
8281     IXMLDOMNodeList_Release(root_list);
8282
8283     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8284     EXPECT_HR(hr, S_OK);
8285     IXMLDOMNode_Release(pr_node);
8286
8287     len = 0;
8288     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8289     EXPECT_HR(hr, S_OK);
8290     ok( len == 3, "length %d\n", len);
8291
8292     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8293     EXPECT_HR(hr, E_INVALIDARG);
8294
8295     node = (void*)0xdeadbeef;
8296     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8297     EXPECT_HR(hr, E_INVALIDARG);
8298     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8299
8300     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8301     EXPECT_HR(hr, E_INVALIDARG);
8302
8303     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8304     EXPECT_HR(hr, S_OK);
8305
8306     IXMLDOMNode_Release(node);
8307     IXMLDOMNamedNodeMap_Release(map);
8308     IXMLDOMElement_Release(element);
8309
8310     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8311     EXPECT_HR(hr, S_OK);
8312
8313     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8314     EXPECT_HR(hr, S_OK);
8315
8316     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8317     EXPECT_HR(hr, S_OK);
8318     IXMLDOMNode_Release(node);
8319
8320     hr = IXMLDOMElement_get_attributes(element, &map);
8321     EXPECT_HR(hr, S_OK);
8322
8323     ptr = qualified_item_tests;
8324     while (ptr->name)
8325     {
8326        node = (void*)0xdeadbeef;
8327        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8328        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8329        if (hr == S_OK)
8330            IXMLDOMNode_Release(node);
8331        else
8332            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8333        ptr++;
8334     }
8335
8336     ptr = named_item_tests;
8337     while (ptr->name)
8338     {
8339        node = (void*)0xdeadbeef;
8340        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8341        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8342        if (hr == S_OK)
8343            IXMLDOMNode_Release(node);
8344        else
8345            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8346        ptr++;
8347     }
8348
8349     IXMLDOMNamedNodeMap_Release(map);
8350
8351     IXMLDOMElement_Release(element);
8352     IXMLDOMDocument_Release(doc);
8353     free_bstrs();
8354 }
8355
8356 static void test_removeQualifiedItem(void)
8357 {
8358     IXMLDOMDocument *doc;
8359     IXMLDOMElement *element;
8360     IXMLDOMNode *pr_node, *node;
8361     IXMLDOMNodeList *root_list;
8362     IXMLDOMNamedNodeMap *map;
8363     VARIANT_BOOL b;
8364     LONG len;
8365     HRESULT hr;
8366
8367     doc = create_document(&IID_IXMLDOMDocument);
8368     if (!doc) return;
8369
8370     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8371     ok( hr == S_OK, "loadXML failed\n");
8372     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8373
8374     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8375     ok( hr == S_OK, "ret %08x\n", hr);
8376
8377     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8378     ok( hr == S_OK, "ret %08x\n", hr);
8379
8380     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8381     ok( hr == S_OK, "ret %08x\n", hr);
8382     IXMLDOMNodeList_Release(root_list);
8383
8384     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8385     ok( hr == S_OK, "ret %08x\n", hr);
8386     IXMLDOMNode_Release(pr_node);
8387
8388     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8389     ok( hr == S_OK, "ret %08x\n", hr);
8390     ok( len == 3, "length %d\n", len);
8391
8392     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8393     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8394
8395     node = (void*)0xdeadbeef;
8396     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8397     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8398     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8399
8400     /* out pointer is optional */
8401     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8402     ok( hr == S_OK, "ret %08x\n", hr);
8403
8404     /* already removed */
8405     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8406     ok( hr == S_FALSE, "ret %08x\n", hr);
8407
8408     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8409     ok( hr == S_OK, "ret %08x\n", hr);
8410     IXMLDOMNode_Release(node);
8411
8412     IXMLDOMNamedNodeMap_Release( map );
8413     IXMLDOMElement_Release( element );
8414     IXMLDOMDocument_Release( doc );
8415     free_bstrs();
8416 }
8417
8418 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8419 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8420 {
8421     VARIANT_BOOL b;
8422     VARIANT var;
8423     HRESULT hr;
8424
8425     VariantInit(&var);
8426     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8427     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8428     VariantClear(&var);
8429
8430     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8431     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8432     VariantClear(&var);
8433
8434     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8435     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8436
8437     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8438     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8439     VariantClear(&var);
8440 }
8441
8442 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8443 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8444 {
8445     VARIANT_BOOL b;
8446     VARIANT var;
8447
8448     VariantInit(&var);
8449     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8450     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8451     VariantClear(&var);
8452
8453     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8454     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8455     VariantClear(&var);
8456
8457     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8458     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8459
8460     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8461     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8462     VariantClear(&var);
8463 }
8464
8465 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8466 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8467 {
8468     VARIANT var;
8469
8470     VariantInit(&var);
8471     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8472     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8473     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8474     V_VT(&var) = VT_DISPATCH;
8475     V_DISPATCH(&var) = NULL;
8476     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8477     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8478     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8479     VariantClear(&var);
8480 }
8481
8482 #define unset_props(doc) _unset_props(__LINE__, doc)
8483 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8484 {
8485     VARIANT var;
8486
8487     VariantInit(&var);
8488     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8489     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8490     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8491     V_VT(&var) = VT_NULL;
8492     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8493     VariantClear(&var);
8494 }
8495
8496 static void test_get_ownerDocument(void)
8497 {
8498     IXMLDOMDocument *doc1, *doc2, *doc3;
8499     IXMLDOMDocument2 *doc, *doc_owner;
8500     IXMLDOMNode *node;
8501     IXMLDOMSchemaCollection *cache;
8502     VARIANT_BOOL b;
8503     VARIANT var;
8504
8505     doc = create_document(&IID_IXMLDOMDocument2);
8506     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8507     if (!doc || !cache)
8508     {
8509         if (doc) IXMLDOMDocument2_Release(doc);
8510         if (cache) IXMLDOMSchemaCollection_Release(cache);
8511         return;
8512     }
8513
8514     VariantInit(&var);
8515
8516     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
8517     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8518
8519     check_default_props(doc);
8520
8521     /* set properties and check that new instances use them */
8522     set_props(doc, cache);
8523     check_set_props(doc);
8524
8525     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8526     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8527
8528     /* new interface keeps props */
8529     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8530     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8531     check_set_props(doc_owner);
8532     IXMLDOMDocument2_Release(doc_owner);
8533
8534     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8535     IXMLDOMNode_Release(node);
8536
8537     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8538
8539     /* reload */
8540     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8541     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8542
8543     /* properties retained even after reload */
8544     check_set_props(doc);
8545
8546     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8547     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8548     IXMLDOMNode_Release(node);
8549
8550     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8551     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8552     check_set_props(doc_owner);
8553
8554     /* changing properties for one instance changes them for all */
8555     unset_props(doc_owner);
8556     check_default_props(doc_owner);
8557     check_default_props(doc);
8558
8559     IXMLDOMSchemaCollection_Release(cache);
8560     IXMLDOMDocument_Release(doc1);
8561     IXMLDOMDocument_Release(doc2);
8562     IXMLDOMDocument_Release(doc3);
8563     IXMLDOMDocument2_Release(doc);
8564     IXMLDOMDocument2_Release(doc_owner);
8565     free_bstrs();
8566 }
8567
8568 static void test_setAttributeNode(void)
8569 {
8570     IXMLDOMDocument *doc, *doc2;
8571     IXMLDOMElement *elem, *elem2;
8572     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8573     VARIANT_BOOL b;
8574     HRESULT hr;
8575     VARIANT v;
8576     BSTR str;
8577     ULONG ref1, ref2;
8578
8579     doc = create_document(&IID_IXMLDOMDocument);
8580     if (!doc) return;
8581
8582     hr = IXMLDOMDocument2_loadXML( doc, _bstr_(complete4A), &b );
8583     ok( hr == S_OK, "loadXML failed\n");
8584     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8585
8586     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8587     ok( hr == S_OK, "got 0x%08x\n", hr);
8588
8589     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8590     ok( hr == S_OK, "got 0x%08x\n", hr);
8591     ok( elem2 != elem, "got same instance\n");
8592
8593     ret_attr = (void*)0xdeadbeef;
8594     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8595     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8596     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8597
8598     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8599     ok( hr == S_OK, "got 0x%08x\n", hr);
8600
8601     ref1 = IXMLDOMElement_AddRef(elem);
8602     IXMLDOMElement_Release(elem);
8603
8604     ret_attr = (void*)0xdeadbeef;
8605     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8606     ok( hr == S_OK, "got 0x%08x\n", hr);
8607     ok( ret_attr == NULL, "got %p\n", ret_attr);
8608
8609     /* no reference added */
8610     ref2 = IXMLDOMElement_AddRef(elem);
8611     IXMLDOMElement_Release(elem);
8612     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8613
8614     EXPECT_CHILDREN(elem);
8615     EXPECT_CHILDREN(elem2);
8616
8617     IXMLDOMElement_Release(elem2);
8618
8619     attr2 = NULL;
8620     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8621     ok( hr == S_OK, "got 0x%08x\n", hr);
8622     ok( attr2 != attr, "got same instance %p\n", attr2);
8623     IXMLDOMAttribute_Release(attr2);
8624
8625     /* try to add it another time */
8626     ret_attr = (void*)0xdeadbeef;
8627     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8628     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8629     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8630
8631     IXMLDOMElement_Release(elem);
8632
8633     /* initially used element is released, attribute still 'has' a container */
8634     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8635     ok( hr == S_OK, "got 0x%08x\n", hr);
8636     ret_attr = (void*)0xdeadbeef;
8637     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8638     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8639     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8640     IXMLDOMElement_Release(elem);
8641
8642     /* add attribute already attached to another document */
8643     doc2 = create_document(&IID_IXMLDOMDocument);
8644
8645     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8646     ok( hr == S_OK, "loadXML failed\n");
8647     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8648
8649     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8650     ok( hr == S_OK, "got 0x%08x\n", hr);
8651     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8652     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8653     IXMLDOMElement_Release(elem);
8654
8655     IXMLDOMAttribute_Release(attr);
8656
8657     /* create element, add attribute, see if it's copied or linked */
8658     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8659     ok( hr == S_OK, "got 0x%08x\n", hr);
8660
8661     attr = NULL;
8662     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8663     ok(hr == S_OK, "got 0x%08x\n", hr);
8664     ok(attr != NULL, "got %p\n", attr);
8665
8666     ref1 = IXMLDOMAttribute_AddRef(attr);
8667     IXMLDOMAttribute_Release(attr);
8668
8669     V_VT(&v) = VT_BSTR;
8670     V_BSTR(&v) = _bstr_("attrvalue1");
8671     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8672     ok( hr == S_OK, "got 0x%08x\n", hr);
8673
8674     str = NULL;
8675     hr = IXMLDOMAttribute_get_xml(attr, &str);
8676     ok( hr == S_OK, "got 0x%08x\n", hr);
8677     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8678         "got %s\n", wine_dbgstr_w(str));
8679     SysFreeString(str);
8680
8681     ret_attr = (void*)0xdeadbeef;
8682     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8683     ok(hr == S_OK, "got 0x%08x\n", hr);
8684     ok(ret_attr == NULL, "got %p\n", ret_attr);
8685
8686     /* attribute reference increased */
8687     ref2 = IXMLDOMAttribute_AddRef(attr);
8688     IXMLDOMAttribute_Release(attr);
8689     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8690
8691     hr = IXMLDOMElement_get_xml(elem, &str);
8692     ok( hr == S_OK, "got 0x%08x\n", hr);
8693     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8694         "got %s\n", wine_dbgstr_w(str));
8695     SysFreeString(str);
8696
8697     V_VT(&v) = VT_BSTR;
8698     V_BSTR(&v) = _bstr_("attrvalue2");
8699     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8700     ok( hr == S_OK, "got 0x%08x\n", hr);
8701
8702     hr = IXMLDOMElement_get_xml(elem, &str);
8703     ok( hr == S_OK, "got 0x%08x\n", hr);
8704     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8705         "got %s\n", wine_dbgstr_w(str));
8706     SysFreeString(str);
8707
8708     IXMLDOMElement_Release(elem);
8709     IXMLDOMAttribute_Release(attr);
8710     IXMLDOMDocument_Release(doc2);
8711     IXMLDOMDocument_Release(doc);
8712     free_bstrs();
8713 }
8714
8715 static void test_createNode(void)
8716 {
8717     IXMLDOMDocument *doc;
8718     IXMLDOMElement *elem;
8719     IXMLDOMNode *node;
8720     VARIANT v, var;
8721     BSTR prefix, str;
8722     HRESULT hr;
8723     ULONG ref;
8724
8725     doc = create_document(&IID_IXMLDOMDocument);
8726     if (!doc) return;
8727
8728     EXPECT_REF(doc, 1);
8729
8730     /* reference count tests */
8731     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8732     ok( hr == S_OK, "got 0x%08x\n", hr);
8733
8734     /* initial reference is 2 */
8735 todo_wine {
8736     EXPECT_REF(elem, 2);
8737     ref = IXMLDOMElement_Release(elem);
8738     ok(ref == 1, "got %d\n", ref);
8739     /* it's released already, attempt to release now will crash it */
8740 }
8741
8742     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8743     ok( hr == S_OK, "got 0x%08x\n", hr);
8744     todo_wine EXPECT_REF(elem, 2);
8745     IXMLDOMDocument_Release(doc);
8746     todo_wine EXPECT_REF(elem, 2);
8747     IXMLDOMElement_Release(elem);
8748
8749     doc = create_document(&IID_IXMLDOMDocument);
8750
8751     /* NODE_ELEMENT nodes */
8752     /* 1. specified namespace */
8753     V_VT(&v) = VT_I4;
8754     V_I4(&v) = NODE_ELEMENT;
8755
8756     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8757     ok( hr == S_OK, "got 0x%08x\n", hr);
8758     prefix = NULL;
8759     hr = IXMLDOMNode_get_prefix(node, &prefix);
8760     ok( hr == S_OK, "got 0x%08x\n", hr);
8761     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8762     SysFreeString(prefix);
8763     IXMLDOMNode_Release(node);
8764
8765     /* 2. default namespace */
8766     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8767     ok( hr == S_OK, "got 0x%08x\n", hr);
8768     prefix = (void*)0xdeadbeef;
8769     hr = IXMLDOMNode_get_prefix(node, &prefix);
8770     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8771     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8772     /* check dump */
8773     hr = IXMLDOMNode_get_xml(node, &str);
8774     ok( hr == S_OK, "got 0x%08x\n", hr);
8775     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8776         "got %s\n", wine_dbgstr_w(str));
8777     SysFreeString(str);
8778
8779     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8780     ok( hr == S_OK, "got 0x%08x\n", hr);
8781
8782     V_VT(&var) = VT_BSTR;
8783     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8784     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8785     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8786
8787     str = NULL;
8788     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8789     ok( hr == S_OK, "got 0x%08x\n", hr);
8790     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8791     SysFreeString(str);
8792
8793     IXMLDOMElement_Release(elem);
8794     IXMLDOMNode_Release(node);
8795
8796     IXMLDOMDocument_Release(doc);
8797     free_bstrs();
8798 }
8799
8800 static const char get_prefix_doc[] =
8801     "<?xml version=\"1.0\" ?>"
8802     "<a xmlns:ns1=\"ns1 href\" />";
8803
8804 static void test_get_prefix(void)
8805 {
8806     IXMLDOMDocumentFragment *fragment;
8807     IXMLDOMCDATASection *cdata;
8808     IXMLDOMElement *element;
8809     IXMLDOMComment *comment;
8810     IXMLDOMDocument *doc;
8811     VARIANT_BOOL b;
8812     HRESULT hr;
8813     BSTR str;
8814
8815     doc = create_document(&IID_IXMLDOMDocument);
8816     if (!doc) return;
8817
8818     /* nodes that can't support prefix */
8819     /* 1. document */
8820     str = (void*)0xdeadbeef;
8821     hr = IXMLDOMDocument_get_prefix(doc, &str);
8822     EXPECT_HR(hr, S_FALSE);
8823     ok(str == NULL, "got %p\n", str);
8824
8825     hr = IXMLDOMDocument_get_prefix(doc, NULL);
8826     EXPECT_HR(hr, E_INVALIDARG);
8827
8828     /* 2. cdata */
8829     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8830     ok(hr == S_OK, "got %08x\n", hr );
8831
8832     str = (void*)0xdeadbeef;
8833     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8834     ok(hr == S_FALSE, "got %08x\n", hr);
8835     ok( str == 0, "got %p\n", str);
8836
8837     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8838     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8839     IXMLDOMCDATASection_Release(cdata);
8840
8841     /* 3. comment */
8842     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8843     ok(hr == S_OK, "got %08x\n", hr );
8844
8845     str = (void*)0xdeadbeef;
8846     hr = IXMLDOMComment_get_prefix(comment, &str);
8847     ok(hr == S_FALSE, "got %08x\n", hr);
8848     ok( str == 0, "got %p\n", str);
8849
8850     hr = IXMLDOMComment_get_prefix(comment, NULL);
8851     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8852     IXMLDOMComment_Release(comment);
8853
8854     /* 4. fragment */
8855     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8856     ok(hr == S_OK, "got %08x\n", hr );
8857
8858     str = (void*)0xdeadbeef;
8859     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8860     ok(hr == S_FALSE, "got %08x\n", hr);
8861     ok( str == 0, "got %p\n", str);
8862
8863     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8864     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8865     IXMLDOMDocumentFragment_Release(fragment);
8866
8867     /* no prefix */
8868     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8869     ok( hr == S_OK, "got 0x%08x\n", hr);
8870
8871     hr = IXMLDOMElement_get_prefix(element, NULL);
8872     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8873
8874     str = (void*)0xdeadbeef;
8875     hr = IXMLDOMElement_get_prefix(element, &str);
8876     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8877     ok( str == 0, "got %p\n", str);
8878
8879     IXMLDOMElement_Release(element);
8880
8881     /* with prefix */
8882     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8883     ok( hr == S_OK, "got 0x%08x\n", hr);
8884
8885     str = (void*)0xdeadbeef;
8886     hr = IXMLDOMElement_get_prefix(element, &str);
8887     ok( hr == S_OK, "got 0x%08x\n", hr);
8888     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8889     SysFreeString(str);
8890
8891     str = (void*)0xdeadbeef;
8892     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8893     ok( hr == S_FALSE, "got 0x%08x\n", hr);
8894     ok( str == 0, "got %p\n", str);
8895
8896     IXMLDOMElement_Release(element);
8897
8898     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8899     EXPECT_HR(hr, S_OK);
8900
8901     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8902     EXPECT_HR(hr, S_OK);
8903
8904     str = (void*)0xdeadbeef;
8905     hr = IXMLDOMElement_get_prefix(element, &str);
8906     EXPECT_HR(hr, S_FALSE);
8907     ok(str == NULL, "got %p\n", str);
8908
8909     str = (void*)0xdeadbeef;
8910     hr = IXMLDOMElement_get_namespaceURI(element, &str);
8911     EXPECT_HR(hr, S_FALSE);
8912     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8913
8914     IXMLDOMDocument_Release(doc);
8915     free_bstrs();
8916 }
8917
8918 static void test_selectSingleNode(void)
8919 {
8920     IXMLDOMDocument *doc;
8921     IXMLDOMNodeList *list;
8922     IXMLDOMNode *node;
8923     VARIANT_BOOL b;
8924     HRESULT hr;
8925     LONG len;
8926
8927     doc = create_document(&IID_IXMLDOMDocument);
8928     if (!doc) return;
8929
8930     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8931     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8932
8933     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8934     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8935
8936     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8937     ok( hr == S_OK, "loadXML failed\n");
8938     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8939
8940     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8941     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8942
8943     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8944     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8945
8946     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8947     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8948
8949     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8950     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8951
8952     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8953     ok(hr == S_OK, "got 0x%08x\n", hr);
8954     IXMLDOMNode_Release(node);
8955
8956     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8957     ok(hr == S_OK, "got 0x%08x\n", hr);
8958     IXMLDOMNodeList_Release(list);
8959
8960     list = (void*)0xdeadbeef;
8961     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8962     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8963     ok(list == (void*)0xdeadbeef, "got %p\n", list);
8964
8965     node = (void*)0xdeadbeef;
8966     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8967     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8968     ok(node == 0, "got %p\n", node);
8969
8970     list = (void*)0xdeadbeef;
8971     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8972     ok(hr == S_OK, "got 0x%08x\n", hr);
8973     len = 1;
8974     hr = IXMLDOMNodeList_get_length(list, &len);
8975     ok(hr == S_OK, "got 0x%08x\n", hr);
8976     ok(len == 0, "got %d\n", len);
8977     IXMLDOMNodeList_Release(list);
8978
8979     IXMLDOMDocument_Release(doc);
8980     free_bstrs();
8981 }
8982
8983 static void test_events(void)
8984 {
8985     IConnectionPointContainer *conn;
8986     IConnectionPoint *point;
8987     IXMLDOMDocument *doc;
8988     HRESULT hr;
8989     VARIANT v;
8990     IDispatch *event;
8991
8992     doc = create_document(&IID_IXMLDOMDocument);
8993     if (!doc) return;
8994
8995     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8996     ok(hr == S_OK, "got 0x%08x\n", hr);
8997
8998     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8999     ok(hr == S_OK, "got 0x%08x\n", hr);
9000     IConnectionPoint_Release(point);
9001     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
9002     ok(hr == S_OK, "got 0x%08x\n", hr);
9003     IConnectionPoint_Release(point);
9004     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
9005     ok(hr == S_OK, "got 0x%08x\n", hr);
9006     IConnectionPoint_Release(point);
9007
9008     IConnectionPointContainer_Release(conn);
9009
9010     /* ready state callback */
9011     VariantInit(&v);
9012     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9013     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9014
9015     event = create_dispevent();
9016     V_VT(&v) = VT_UNKNOWN;
9017     V_UNKNOWN(&v) = (IUnknown*)event;
9018
9019     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9020     ok(hr == S_OK, "got 0x%08x\n", hr);
9021     EXPECT_REF(event, 2);
9022
9023     V_VT(&v) = VT_DISPATCH;
9024     V_DISPATCH(&v) = event;
9025
9026     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9027     ok(hr == S_OK, "got 0x%08x\n", hr);
9028     EXPECT_REF(event, 2);
9029
9030     /* VT_NULL doesn't reset event handler */
9031     V_VT(&v) = VT_NULL;
9032     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9033     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9034     EXPECT_REF(event, 2);
9035
9036     V_VT(&v) = VT_DISPATCH;
9037     V_DISPATCH(&v) = NULL;
9038
9039     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9040     ok(hr == S_OK, "got 0x%08x\n", hr);
9041     EXPECT_REF(event, 1);
9042
9043     V_VT(&v) = VT_UNKNOWN;
9044     V_DISPATCH(&v) = NULL;
9045     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9046     ok(hr == S_OK, "got 0x%08x\n", hr);
9047
9048     IDispatch_Release(event);
9049
9050     IXMLDOMDocument_Release(doc);
9051 }
9052
9053 static void test_createProcessingInstruction(void)
9054 {
9055     static const WCHAR bodyW[] = {'t','e','s','t',0};
9056     IXMLDOMProcessingInstruction *pi;
9057     IXMLDOMDocument *doc;
9058     WCHAR buff[10];
9059     HRESULT hr;
9060
9061     doc = create_document(&IID_IXMLDOMDocument);
9062     if (!doc) return;
9063
9064     /* test for BSTR handling, pass broken BSTR */
9065     memcpy(&buff[2], bodyW, sizeof(bodyW));
9066     /* just a big length */
9067     *(DWORD*)buff = 0xf0f0;
9068     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9069     ok(hr == S_OK, "got 0x%08x\n", hr);
9070
9071     IXMLDOMProcessingInstruction_Release(pi);
9072     IXMLDOMDocument_Release(doc);
9073 }
9074
9075 static void test_put_nodeTypedValue(void)
9076 {
9077     IXMLDOMDocument *doc;
9078     IXMLDOMElement *elem;
9079     VARIANT type;
9080     HRESULT hr;
9081
9082     doc = create_document(&IID_IXMLDOMDocument);
9083     if (!doc) return;
9084
9085     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9086     ok(hr == S_OK, "got 0x%08x\n", hr);
9087
9088     V_VT(&type) = VT_EMPTY;
9089     hr = IXMLDOMElement_get_dataType(elem, &type);
9090     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9091     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9092
9093     /* set typed value for untyped node */
9094     V_VT(&type) = VT_I1;
9095     V_I1(&type) = 1;
9096     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9097     ok(hr == S_OK, "got 0x%08x\n", hr);
9098
9099     V_VT(&type) = VT_EMPTY;
9100     hr = IXMLDOMElement_get_dataType(elem, &type);
9101     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9102     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9103
9104     /* no type info stored */
9105     V_VT(&type) = VT_EMPTY;
9106     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9107     ok(hr == S_OK, "got 0x%08x\n", hr);
9108     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9109     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9110        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9111     VariantClear(&type);
9112
9113     IXMLDOMElement_Release(elem);
9114     IXMLDOMDocument_Release(doc);
9115     free_bstrs();
9116 }
9117
9118 static void test_get_xml(void)
9119 {
9120     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9121     static const char fooA[] = "<foo/>";
9122     IXMLDOMProcessingInstruction *pi;
9123     IXMLDOMNode *first;
9124     IXMLDOMElement *elem = NULL;
9125     IXMLDOMDocument *doc;
9126     VARIANT_BOOL b;
9127     VARIANT v;
9128     BSTR xml;
9129     HRESULT hr;
9130
9131     doc = create_document(&IID_IXMLDOMDocument);
9132     if (!doc) return;
9133
9134     b = VARIANT_TRUE;
9135     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9136     ok(hr == S_OK, "got 0x%08x\n", hr);
9137     ok( b == VARIANT_TRUE, "got %d\n", b);
9138
9139     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9140                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9141     ok(hr == S_OK, "got 0x%08x\n", hr);
9142
9143     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9144     ok(hr == S_OK, "got 0x%08x\n", hr);
9145
9146     V_UNKNOWN(&v) = (IUnknown*)first;
9147     V_VT(&v) = VT_UNKNOWN;
9148
9149     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9150     ok(hr == S_OK, "got 0x%08x\n", hr);
9151
9152     IXMLDOMProcessingInstruction_Release(pi);
9153     IXMLDOMNode_Release(first);
9154
9155     hr = IXMLDOMDocument_get_xml(doc, &xml);
9156     ok(hr == S_OK, "got 0x%08x\n", hr);
9157
9158     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9159         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9160     SysFreeString(xml);
9161
9162     IXMLDOMDocument_Release(doc);
9163
9164     doc = create_document(&IID_IXMLDOMDocument);
9165
9166     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9167     ok(hr == S_OK, "got 0x%08x\n", hr);
9168
9169     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9170     ok(hr == S_OK, "got 0x%08x\n", hr);
9171
9172     hr = IXMLDOMDocument_get_xml(doc, &xml);
9173     ok(hr == S_OK, "got 0x%08x\n", hr);
9174
9175     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9176         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9177     SysFreeString(xml);
9178
9179     IXMLDOMElement_Release(elem);
9180     IXMLDOMDocument_Release(doc);
9181
9182     free_bstrs();
9183 }
9184
9185 static void test_xsltemplate(void)
9186 {
9187     IXSLTemplate *template;
9188     IXSLProcessor *processor;
9189     IXMLDOMDocument *doc, *doc2;
9190     IStream *stream;
9191     VARIANT_BOOL b;
9192     HRESULT hr;
9193     ULONG ref1, ref2;
9194     VARIANT v;
9195
9196     template = create_xsltemplate(&IID_IXSLTemplate);
9197     if (!template) return;
9198
9199     /* works as reset */
9200     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9201     ok(hr == S_OK, "got 0x%08x\n", hr);
9202
9203     doc = create_document(&IID_IXMLDOMDocument);
9204
9205     b = VARIANT_TRUE;
9206     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9207     ok(hr == S_OK, "got 0x%08x\n", hr);
9208     ok( b == VARIANT_TRUE, "got %d\n", b);
9209
9210     /* putref with non-xsl document */
9211     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9212     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9213
9214     b = VARIANT_TRUE;
9215     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9216     ok(hr == S_OK, "got 0x%08x\n", hr);
9217     ok( b == VARIANT_TRUE, "got %d\n", b);
9218
9219     /* not a freethreaded document */
9220     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9221     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9222
9223     IXMLDOMDocument_Release(doc);
9224
9225     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9226     if (hr != S_OK)
9227     {
9228         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9229         IXSLTemplate_Release(template);
9230         return;
9231     }
9232
9233     b = VARIANT_TRUE;
9234     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9235     ok(hr == S_OK, "got 0x%08x\n", hr);
9236     ok( b == VARIANT_TRUE, "got %d\n", b);
9237
9238     /* freethreaded document */
9239     ref1 = IXMLDOMDocument_AddRef(doc);
9240     IXMLDOMDocument_Release(doc);
9241     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9242     ok(hr == S_OK, "got 0x%08x\n", hr);
9243     ref2 = IXMLDOMDocument_AddRef(doc);
9244     IXMLDOMDocument_Release(doc);
9245     ok(ref2 > ref1, "got %d\n", ref2);
9246
9247     /* processor */
9248     hr = IXSLTemplate_createProcessor(template, NULL);
9249     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9250
9251     EXPECT_REF(template, 1);
9252     hr = IXSLTemplate_createProcessor(template, &processor);
9253     ok(hr == S_OK, "got 0x%08x\n", hr);
9254     EXPECT_REF(template, 2);
9255
9256     /* input no set yet */
9257     V_VT(&v) = VT_BSTR;
9258     V_BSTR(&v) = NULL;
9259     hr = IXSLProcessor_get_input(processor, &v);
9260 todo_wine {
9261     ok(hr == S_OK, "got 0x%08x\n", hr);
9262     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9263 }
9264
9265     hr = IXSLProcessor_get_output(processor, NULL);
9266     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9267
9268     /* reset before it was set */
9269     V_VT(&v) = VT_EMPTY;
9270     hr = IXSLProcessor_put_output(processor, v);
9271     ok(hr == S_OK, "got 0x%08x\n", hr);
9272
9273     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9274     EXPECT_REF(stream, 1);
9275
9276     V_VT(&v) = VT_UNKNOWN;
9277     V_UNKNOWN(&v) = (IUnknown*)stream;
9278     hr = IXSLProcessor_put_output(processor, v);
9279     ok(hr == S_OK, "got 0x%08x\n", hr);
9280
9281     /* it seems processor grabs 2 references */
9282     todo_wine EXPECT_REF(stream, 3);
9283
9284     V_VT(&v) = VT_EMPTY;
9285     hr = IXSLProcessor_get_output(processor, &v);
9286     ok(hr == S_OK, "got 0x%08x\n", hr);
9287     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9288     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9289
9290     todo_wine EXPECT_REF(stream, 4);
9291     VariantClear(&v);
9292
9293     hr = IXSLProcessor_transform(processor, NULL);
9294     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9295
9296     /* reset and check stream refcount */
9297     V_VT(&v) = VT_EMPTY;
9298     hr = IXSLProcessor_put_output(processor, v);
9299     ok(hr == S_OK, "got 0x%08x\n", hr);
9300
9301     EXPECT_REF(stream, 1);
9302
9303     IStream_Release(stream);
9304
9305     /* no output interface set, check output */
9306     doc2 = create_document(&IID_IXMLDOMDocument);
9307
9308     b = VARIANT_TRUE;
9309     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9310     ok(hr == S_OK, "got 0x%08x\n", hr);
9311     ok( b == VARIANT_TRUE, "got %d\n", b);
9312
9313     V_VT(&v) = VT_UNKNOWN;
9314     V_UNKNOWN(&v) = (IUnknown*)doc2;
9315     hr = IXSLProcessor_put_input(processor, v);
9316     ok(hr == S_OK, "got 0x%08x\n", hr);
9317
9318     hr = IXSLProcessor_transform(processor, &b);
9319     ok(hr == S_OK, "got 0x%08x\n", hr);
9320
9321     V_VT(&v) = VT_EMPTY;
9322     hr = IXSLProcessor_get_output(processor, &v);
9323     ok(hr == S_OK, "got 0x%08x\n", hr);
9324     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9325     /* we currently output one '\n' instead of empty string */
9326     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9327     IXMLDOMDocument_Release(doc2);
9328     VariantClear(&v);
9329
9330     IXSLProcessor_Release(processor);
9331
9332     /* drop reference */
9333     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9334     ok(hr == S_OK, "got 0x%08x\n", hr);
9335     ref2 = IXMLDOMDocument_AddRef(doc);
9336     IXMLDOMDocument_Release(doc);
9337     ok(ref2 == ref1, "got %d\n", ref2);
9338
9339     IXMLDOMDocument_Release(doc);
9340     IXSLTemplate_Release(template);
9341     free_bstrs();
9342 }
9343
9344 static void test_insertBefore(void)
9345 {
9346     IXMLDOMDocument *doc, *doc2;
9347     IXMLDOMAttribute *attr;
9348     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9349     IXMLDOMNode *node, *newnode;
9350     HRESULT hr;
9351     VARIANT v;
9352     BSTR p;
9353
9354     doc = create_document(&IID_IXMLDOMDocument);
9355
9356     /* insertBefore behaviour for attribute node */
9357     V_VT(&v) = VT_I4;
9358     V_I4(&v) = NODE_ATTRIBUTE;
9359
9360     attr = NULL;
9361     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9362     ok(hr == S_OK, "got 0x%08x\n", hr);
9363     ok(attr != NULL, "got %p\n", attr);
9364
9365     /* attribute to attribute */
9366     V_VT(&v) = VT_I4;
9367     V_I4(&v) = NODE_ATTRIBUTE;
9368     newnode = NULL;
9369     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9370     ok(hr == S_OK, "got 0x%08x\n", hr);
9371     ok(newnode != NULL, "got %p\n", newnode);
9372
9373     V_VT(&v) = VT_NULL;
9374     node = (void*)0xdeadbeef;
9375     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9376     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9377     ok(node == NULL, "got %p\n", node);
9378
9379     V_VT(&v) = VT_UNKNOWN;
9380     V_UNKNOWN(&v) = (IUnknown*)attr;
9381     node = (void*)0xdeadbeef;
9382     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9383     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9384     ok(node == NULL, "got %p\n", node);
9385     IXMLDOMNode_Release(newnode);
9386
9387     /* cdata to attribute */
9388     V_VT(&v) = VT_I4;
9389     V_I4(&v) = NODE_CDATA_SECTION;
9390     newnode = NULL;
9391     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9392     ok(hr == S_OK, "got 0x%08x\n", hr);
9393     ok(newnode != NULL, "got %p\n", newnode);
9394
9395     V_VT(&v) = VT_NULL;
9396     node = (void*)0xdeadbeef;
9397     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9398     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9399     ok(node == NULL, "got %p\n", node);
9400     IXMLDOMNode_Release(newnode);
9401
9402     /* comment to attribute */
9403     V_VT(&v) = VT_I4;
9404     V_I4(&v) = NODE_COMMENT;
9405     newnode = NULL;
9406     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9407     ok(hr == S_OK, "got 0x%08x\n", hr);
9408     ok(newnode != NULL, "got %p\n", newnode);
9409
9410     V_VT(&v) = VT_NULL;
9411     node = (void*)0xdeadbeef;
9412     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9413     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9414     ok(node == NULL, "got %p\n", node);
9415     IXMLDOMNode_Release(newnode);
9416
9417     /* element to attribute */
9418     V_VT(&v) = VT_I4;
9419     V_I4(&v) = NODE_ELEMENT;
9420     newnode = NULL;
9421     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9422     ok(hr == S_OK, "got 0x%08x\n", hr);
9423     ok(newnode != NULL, "got %p\n", newnode);
9424
9425     V_VT(&v) = VT_NULL;
9426     node = (void*)0xdeadbeef;
9427     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9428     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9429     ok(node == NULL, "got %p\n", node);
9430     IXMLDOMNode_Release(newnode);
9431
9432     /* pi to attribute */
9433     V_VT(&v) = VT_I4;
9434     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9435     newnode = NULL;
9436     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9437     ok(hr == S_OK, "got 0x%08x\n", hr);
9438     ok(newnode != NULL, "got %p\n", newnode);
9439
9440     V_VT(&v) = VT_NULL;
9441     node = (void*)0xdeadbeef;
9442     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9443     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9444     ok(node == NULL, "got %p\n", node);
9445     IXMLDOMNode_Release(newnode);
9446     IXMLDOMAttribute_Release(attr);
9447
9448     /* insertBefore for elements */
9449     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9450     ok(hr == S_OK, "got 0x%08x\n", hr);
9451
9452     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9453     ok(hr == S_OK, "got 0x%08x\n", hr);
9454
9455     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9456     ok(hr == S_OK, "got 0x%08x\n", hr);
9457
9458     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9459     ok(hr == S_OK, "got 0x%08x\n", hr);
9460
9461     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9462     ok(hr == S_OK, "got 0x%08x\n", hr);
9463
9464     EXPECT_NO_CHILDREN(elem1);
9465     EXPECT_NO_CHILDREN(elem2);
9466     EXPECT_NO_CHILDREN(elem3);
9467
9468     todo_wine EXPECT_REF(elem2, 2);
9469
9470     V_VT(&v) = VT_DISPATCH;
9471     V_DISPATCH(&v) = NULL;
9472     node = NULL;
9473     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9474     ok(hr == S_OK, "got 0x%08x\n", hr);
9475     ok(node == (void*)elem4, "got %p\n", node);
9476
9477     EXPECT_CHILDREN(elem1);
9478     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9479     EXPECT_HR(hr, S_OK);
9480     IXMLDOMElement_Release(elem4);
9481
9482     EXPECT_NO_CHILDREN(elem1);
9483
9484     V_VT(&v) = VT_NULL;
9485     node = NULL;
9486     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9487     ok(hr == S_OK, "got 0x%08x\n", hr);
9488     ok(node == (void*)elem2, "got %p\n", node);
9489
9490     EXPECT_CHILDREN(elem1);
9491     todo_wine EXPECT_REF(elem2, 3);
9492     IXMLDOMNode_Release(node);
9493
9494     /* again for already linked node */
9495     V_VT(&v) = VT_NULL;
9496     node = NULL;
9497     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9498     ok(hr == S_OK, "got 0x%08x\n", hr);
9499     ok(node == (void*)elem2, "got %p\n", node);
9500
9501     EXPECT_CHILDREN(elem1);
9502
9503     /* increments each time */
9504     todo_wine EXPECT_REF(elem2, 3);
9505     IXMLDOMNode_Release(node);
9506
9507     /* try to add to another element */
9508     V_VT(&v) = VT_NULL;
9509     node = (void*)0xdeadbeef;
9510     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9511     ok(hr == S_OK, "got 0x%08x\n", hr);
9512     ok(node == (void*)elem2, "got %p\n", node);
9513
9514     EXPECT_CHILDREN(elem3);
9515     EXPECT_NO_CHILDREN(elem1);
9516
9517     IXMLDOMNode_Release(node);
9518
9519     /* cross document case - try to add as child to a node created with other doc */
9520     doc2 = create_document(&IID_IXMLDOMDocument);
9521
9522     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9523     ok(hr == S_OK, "got 0x%08x\n", hr);
9524     todo_wine EXPECT_REF(elem4, 2);
9525
9526     /* same name, another instance */
9527     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9528     ok(hr == S_OK, "got 0x%08x\n", hr);
9529     todo_wine EXPECT_REF(elem5, 2);
9530
9531     todo_wine EXPECT_REF(elem3, 2);
9532     V_VT(&v) = VT_NULL;
9533     node = NULL;
9534     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9535     ok(hr == S_OK, "got 0x%08x\n", hr);
9536     ok(node == (void*)elem4, "got %p\n", node);
9537     todo_wine EXPECT_REF(elem4, 3);
9538     todo_wine EXPECT_REF(elem3, 2);
9539     IXMLDOMNode_Release(node);
9540
9541     V_VT(&v) = VT_NULL;
9542     node = NULL;
9543     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9544     ok(hr == S_OK, "got 0x%08x\n", hr);
9545     ok(node == (void*)elem5, "got %p\n", node);
9546     todo_wine EXPECT_REF(elem4, 2);
9547     todo_wine EXPECT_REF(elem5, 3);
9548     IXMLDOMNode_Release(node);
9549
9550     IXMLDOMDocument_Release(doc2);
9551
9552     IXMLDOMElement_Release(elem1);
9553     IXMLDOMElement_Release(elem2);
9554     IXMLDOMElement_Release(elem3);
9555     IXMLDOMElement_Release(elem4);
9556     IXMLDOMElement_Release(elem5);
9557
9558     /* elements with same default namespace */
9559     V_VT(&v) = VT_I4;
9560     V_I4(&v) = NODE_ELEMENT;
9561     elem1 = NULL;
9562     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9563     ok(hr == S_OK, "got 0x%08x\n", hr);
9564     ok(elem1 != NULL, "got %p\n", elem1);
9565
9566     V_VT(&v) = VT_I4;
9567     V_I4(&v) = NODE_ELEMENT;
9568     elem2 = NULL;
9569     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9570     ok(hr == S_OK, "got 0x%08x\n", hr);
9571     ok(elem2 != NULL, "got %p\n", elem2);
9572
9573     /* check contents so far */
9574     p = NULL;
9575     hr = IXMLDOMElement_get_xml(elem1, &p);
9576     ok(hr == S_OK, "got 0x%08x\n", hr);
9577     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9578     SysFreeString(p);
9579
9580     p = NULL;
9581     hr = IXMLDOMElement_get_xml(elem2, &p);
9582     ok(hr == S_OK, "got 0x%08x\n", hr);
9583     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9584     SysFreeString(p);
9585
9586     V_VT(&v) = VT_NULL;
9587     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9588     ok(hr == S_OK, "got 0x%08x\n", hr);
9589
9590     /* get_xml depends on context, for top node it omits child namespace attribute,
9591        but at child level it's still returned */
9592     p = NULL;
9593     hr = IXMLDOMElement_get_xml(elem1, &p);
9594     ok(hr == S_OK, "got 0x%08x\n", hr);
9595     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9596         "got %s\n", wine_dbgstr_w(p));
9597     SysFreeString(p);
9598
9599     p = NULL;
9600     hr = IXMLDOMElement_get_xml(elem2, &p);
9601     ok(hr == S_OK, "got 0x%08x\n", hr);
9602     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9603     SysFreeString(p);
9604
9605     IXMLDOMElement_Release(elem1);
9606     IXMLDOMElement_Release(elem2);
9607
9608     /* child without default namespace added to node with default namespace */
9609     V_VT(&v) = VT_I4;
9610     V_I4(&v) = NODE_ELEMENT;
9611     elem1 = NULL;
9612     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9613     ok(hr == S_OK, "got 0x%08x\n", hr);
9614     ok(elem1 != NULL, "got %p\n", elem1);
9615
9616     V_VT(&v) = VT_I4;
9617     V_I4(&v) = NODE_ELEMENT;
9618     elem2 = NULL;
9619     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9620     ok(hr == S_OK, "got 0x%08x\n", hr);
9621     ok(elem2 != NULL, "got %p\n", elem2);
9622
9623     EXPECT_REF(elem2, 1);
9624     V_VT(&v) = VT_NULL;
9625     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9626     ok(hr == S_OK, "got 0x%08x\n", hr);
9627     EXPECT_REF(elem2, 1);
9628
9629     p = NULL;
9630     hr = IXMLDOMElement_get_xml(elem2, &p);
9631     ok(hr == S_OK, "got 0x%08x\n", hr);
9632     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9633     SysFreeString(p);
9634
9635     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9636     ok(hr == S_OK, "got 0x%08x\n", hr);
9637
9638     p = NULL;
9639     hr = IXMLDOMElement_get_xml(elem2, &p);
9640     ok(hr == S_OK, "got 0x%08x\n", hr);
9641     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9642     SysFreeString(p);
9643
9644     IXMLDOMElement_Release(elem1);
9645     IXMLDOMElement_Release(elem2);
9646     IXMLDOMDocument_Release(doc);
9647 }
9648
9649 static void test_appendChild(void)
9650 {
9651     IXMLDOMDocument *doc, *doc2;
9652     IXMLDOMElement *elem, *elem2;
9653     HRESULT hr;
9654
9655     doc = create_document(&IID_IXMLDOMDocument);
9656     doc2 = create_document(&IID_IXMLDOMDocument);
9657
9658     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9659     ok(hr == S_OK, "got 0x%08x\n", hr);
9660
9661     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9662     ok(hr == S_OK, "got 0x%08x\n", hr);
9663
9664     EXPECT_REF(doc, 1);
9665     todo_wine EXPECT_REF(elem, 2);
9666     EXPECT_REF(doc2, 1);
9667     todo_wine EXPECT_REF(elem2, 2);
9668     EXPECT_NO_CHILDREN(doc);
9669     EXPECT_NO_CHILDREN(doc2);
9670
9671     /* append from another document */
9672     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9673     ok(hr == S_OK, "got 0x%08x\n", hr);
9674
9675     EXPECT_REF(doc, 1);
9676     todo_wine EXPECT_REF(elem, 2);
9677     EXPECT_REF(doc2, 1);
9678     todo_wine EXPECT_REF(elem2, 2);
9679     EXPECT_NO_CHILDREN(doc);
9680     EXPECT_CHILDREN(doc2);
9681
9682     IXMLDOMElement_Release(elem);
9683     IXMLDOMElement_Release(elem2);
9684     IXMLDOMDocument_Release(doc);
9685     IXMLDOMDocument_Release(doc2);
9686 }
9687
9688 static void test_get_doctype(void)
9689 {
9690     IXMLDOMDocumentType *doctype;
9691     IXMLDOMDocument *doc;
9692     HRESULT hr;
9693
9694     doc = create_document(&IID_IXMLDOMDocument);
9695
9696     hr = IXMLDOMDocument_get_doctype(doc, NULL);
9697     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9698
9699     doctype = (void*)0xdeadbeef;
9700     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9701     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9702     ok(doctype == NULL, "got %p\n", doctype);
9703
9704     IXMLDOMDocument_Release(doc);
9705 }
9706
9707 static void test_get_tagName(void)
9708 {
9709     IXMLDOMDocument *doc;
9710     IXMLDOMElement *elem, *elem2;
9711     HRESULT hr;
9712     BSTR str;
9713
9714     doc = create_document(&IID_IXMLDOMDocument);
9715
9716     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9717     ok(hr == S_OK, "got 0x%08x\n", hr);
9718
9719     hr = IXMLDOMElement_get_tagName(elem, NULL);
9720     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9721
9722     str = NULL;
9723     hr = IXMLDOMElement_get_tagName(elem, &str);
9724     ok(hr == S_OK, "got 0x%08x\n", hr);
9725     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9726     SysFreeString(str);
9727
9728     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9729     ok(hr == S_OK, "got 0x%08x\n", hr);
9730
9731     str = NULL;
9732     hr = IXMLDOMElement_get_tagName(elem2, &str);
9733     ok(hr == S_OK, "got 0x%08x\n", hr);
9734     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9735     SysFreeString(str);
9736
9737     IXMLDOMDocument_Release(elem);
9738     IXMLDOMDocument_Release(elem2);
9739     IXMLDOMDocument_Release(doc);
9740     free_bstrs();
9741 }
9742
9743 typedef struct {
9744     DOMNodeType type;
9745     const char *name;
9746     VARTYPE vt;
9747     HRESULT hr;
9748 } node_type_t;
9749
9750 static const node_type_t get_datatype[] = {
9751     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
9752     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
9753     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
9754     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
9755     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
9756     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
9757     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
9758     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
9759     { 0 }
9760 };
9761
9762 static void test_get_dataType(void)
9763 {
9764     const node_type_t *entry = get_datatype;
9765     IXMLDOMDocument *doc;
9766
9767     doc = create_document(&IID_IXMLDOMDocument);
9768
9769     while (entry->type)
9770     {
9771         IXMLDOMNode *node = NULL;
9772         VARIANT var, type;
9773         HRESULT hr;
9774
9775         V_VT(&var) = VT_I4;
9776         V_I4(&var) = entry->type;
9777         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9778         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9779
9780         hr = IXMLDOMNode_get_dataType(node, NULL);
9781         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9782
9783         VariantInit(&type);
9784         hr = IXMLDOMNode_get_dataType(node, &type);
9785         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9786             hr, entry->hr, entry->type);
9787         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9788             V_VT(&type), entry->vt, entry->type);
9789         VariantClear(&type);
9790
9791         IXMLDOMNode_Release(node);
9792
9793         entry++;
9794     }
9795
9796     IXMLDOMDocument_Release(doc);
9797     free_bstrs();
9798 }
9799
9800 typedef struct _get_node_typestring_t {
9801     DOMNodeType type;
9802     const char *string;
9803 } get_node_typestring_t;
9804
9805 static const get_node_typestring_t get_node_typestring[] = {
9806     { NODE_ELEMENT,                "element"               },
9807     { NODE_ATTRIBUTE,              "attribute"             },
9808     { NODE_TEXT,                   "text"                  },
9809     { NODE_CDATA_SECTION ,         "cdatasection"          },
9810     { NODE_ENTITY_REFERENCE,       "entityreference"       },
9811     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9812     { NODE_COMMENT,                "comment"               },
9813     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
9814     { 0 }
9815 };
9816
9817 static void test_get_nodeTypeString(void)
9818 {
9819     const get_node_typestring_t *entry = get_node_typestring;
9820     IXMLDOMDocument *doc;
9821     HRESULT hr;
9822     BSTR str;
9823
9824     doc = create_document(&IID_IXMLDOMDocument);
9825
9826     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9827     ok(hr == S_OK, "got 0x%08x\n", hr);
9828     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9829     SysFreeString(str);
9830
9831     while (entry->type)
9832     {
9833         IXMLDOMNode *node = NULL;
9834         VARIANT var;
9835
9836         V_VT(&var) = VT_I4;
9837         V_I4(&var) = entry->type;
9838         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9839         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9840
9841         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9842         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9843
9844         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9845         ok(hr == S_OK, "got 0x%08x\n", hr);
9846         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9847             wine_dbgstr_w(str), entry->string, entry->type);
9848         SysFreeString(str);
9849         IXMLDOMNode_Release(node);
9850
9851         entry++;
9852     }
9853
9854     IXMLDOMDocument_Release(doc);
9855     free_bstrs();
9856 }
9857
9858 typedef struct _get_attributes_t {
9859     DOMNodeType type;
9860     HRESULT hr;
9861 } get_attributes_t;
9862
9863 static const get_attributes_t get_attributes[] = {
9864     { NODE_ATTRIBUTE,              S_FALSE },
9865     { NODE_TEXT,                   S_FALSE },
9866     { NODE_CDATA_SECTION ,         S_FALSE },
9867     { NODE_ENTITY_REFERENCE,       S_FALSE },
9868     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9869     { NODE_COMMENT,                S_FALSE },
9870     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
9871     { 0 }
9872 };
9873
9874 static void test_get_attributes(void)
9875 {
9876     const get_attributes_t *entry = get_attributes;
9877     IXMLDOMNamedNodeMap *map;
9878     IXMLDOMDocument *doc;
9879     IXMLDOMNode *node, *node2;
9880     VARIANT_BOOL b;
9881     HRESULT hr;
9882     BSTR str;
9883     LONG length;
9884
9885     doc = create_document(&IID_IXMLDOMDocument);
9886
9887     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9888     ok(hr == S_OK, "got %08x\n", hr);
9889
9890     hr = IXMLDOMDocument_get_attributes(doc, NULL);
9891     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9892
9893     map = (void*)0xdeadbeef;
9894     hr = IXMLDOMDocument_get_attributes(doc, &map);
9895     ok(hr == S_FALSE, "got %08x\n", hr);
9896     ok(map == NULL, "got %p\n", map);
9897
9898     /* first child is <?xml ?> */
9899     hr = IXMLDOMDocument_get_firstChild(doc, &node);
9900     ok(hr == S_OK, "got %08x\n", hr);
9901
9902     hr = IXMLDOMNode_get_attributes(node, &map);
9903     ok(hr == S_OK, "got %08x\n", hr);
9904
9905     length = -1;
9906     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9907     EXPECT_HR(hr, S_OK);
9908     todo_wine ok(length == 1, "got %d\n", length);
9909
9910     if (hr == S_OK && length == 1)
9911     {
9912         IXMLDOMAttribute *attr;
9913         DOMNodeType type;
9914         VARIANT v;
9915
9916         node2 = NULL;
9917         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9918         EXPECT_HR(hr, S_OK);
9919         ok(node != NULL, "got %p\n", node2);
9920
9921         hr = IXMLDOMNode_get_nodeName(node2, &str);
9922         EXPECT_HR(hr, S_OK);
9923         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9924         SysFreeString(str);
9925
9926         length = -1;
9927         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9928         EXPECT_HR(hr, S_OK);
9929         ok(length == 1, "got %d\n", length);
9930
9931         type = -1;
9932         hr = IXMLDOMNode_get_nodeType(node2, &type);
9933         EXPECT_HR(hr, S_OK);
9934         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9935
9936         hr = IXMLDOMNode_get_xml(node, &str);
9937         EXPECT_HR(hr, S_OK);
9938         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9939         SysFreeString(str);
9940
9941         hr = IXMLDOMNode_get_text(node, &str);
9942         EXPECT_HR(hr, S_OK);
9943         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9944         SysFreeString(str);
9945
9946         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9947         EXPECT_HR(hr, S_OK);
9948
9949         length = -1;
9950         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9951         EXPECT_HR(hr, S_OK);
9952         ok(length == 0, "got %d\n", length);
9953
9954         hr = IXMLDOMNode_get_xml(node, &str);
9955         EXPECT_HR(hr, S_OK);
9956         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9957         SysFreeString(str);
9958
9959         hr = IXMLDOMNode_get_text(node, &str);
9960         EXPECT_HR(hr, S_OK);
9961         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9962         SysFreeString(str);
9963
9964         IXMLDOMNamedNodeMap_Release(map);
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 == 0, "got %d\n", length);
9973
9974         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9975         EXPECT_HR(hr, S_OK);
9976
9977         V_VT(&v) = VT_BSTR;
9978         V_BSTR(&v) = _bstr_("UTF-8");
9979         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9980         EXPECT_HR(hr, S_OK);
9981
9982         EXPECT_REF(attr, 2);
9983         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9984         EXPECT_HR(hr, S_OK);
9985         EXPECT_REF(attr, 2);
9986
9987         hr = IXMLDOMNode_get_attributes(node, &map);
9988         ok(hr == S_OK, "got %08x\n", hr);
9989
9990         length = -1;
9991         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9992         EXPECT_HR(hr, S_OK);
9993         ok(length == 1, "got %d\n", length);
9994
9995         hr = IXMLDOMNode_get_xml(node, &str);
9996         EXPECT_HR(hr, S_OK);
9997         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9998         SysFreeString(str);
9999
10000         hr = IXMLDOMNode_get_text(node, &str);
10001         EXPECT_HR(hr, S_OK);
10002         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
10003         SysFreeString(str);
10004
10005         IXMLDOMNamedNodeMap_Release(map);
10006         IXMLDOMNode_Release(node2);
10007     }
10008
10009     IXMLDOMNode_Release(node);
10010
10011     /* last child is element */
10012     EXPECT_REF(doc, 1);
10013     hr = IXMLDOMDocument_get_lastChild(doc, &node);
10014     ok(hr == S_OK, "got %08x\n", hr);
10015     EXPECT_REF(doc, 1);
10016
10017     EXPECT_REF(node, 1);
10018     hr = IXMLDOMNode_get_attributes(node, &map);
10019     ok(hr == S_OK, "got %08x\n", hr);
10020     EXPECT_REF(node, 1);
10021     EXPECT_REF(doc, 1);
10022
10023     EXPECT_REF(map, 1);
10024     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10025     ok(hr == S_OK, "got %08x\n", hr);
10026     EXPECT_REF(node, 1);
10027     EXPECT_REF(node2, 1);
10028     EXPECT_REF(map, 1);
10029     EXPECT_REF(doc, 1);
10030     IXMLDOMNode_Release(node2);
10031
10032     /* release node before map release, map still works */
10033     IXMLDOMNode_Release(node);
10034
10035     length = 0;
10036     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10037     ok(hr == S_OK, "got %08x\n", hr);
10038     ok(length == 1, "got %d\n", length);
10039
10040     node2 = NULL;
10041     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10042     ok(hr == S_OK, "got %08x\n", hr);
10043     EXPECT_REF(node2, 1);
10044     IXMLDOMNode_Release(node2);
10045
10046     IXMLDOMNamedNodeMap_Release(map);
10047
10048     while (entry->type)
10049     {
10050         VARIANT var;
10051
10052         node = NULL;
10053
10054         V_VT(&var) = VT_I4;
10055         V_I4(&var) = entry->type;
10056         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10057         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10058
10059         hr = IXMLDOMNode_get_attributes(node, NULL);
10060         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10061
10062         map = (void*)0xdeadbeef;
10063         hr = IXMLDOMNode_get_attributes(node, &map);
10064         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10065             hr, entry->hr, entry->type);
10066         ok(map == NULL, "got %p\n", map);
10067
10068         IXMLDOMNode_Release(node);
10069
10070         entry++;
10071     }
10072
10073     IXMLDOMDocument_Release(doc);
10074     free_bstrs();
10075 }
10076
10077 static void test_selection(void)
10078 {
10079     IXMLDOMSelection *selection, *selection2;
10080     IEnumVARIANT *enum1, *enum2, *enum3;
10081     IXMLDOMNodeList *list;
10082     IXMLDOMDocument *doc;
10083     IDispatchEx *dispex;
10084     IXMLDOMNode *node;
10085     IDispatch *disp;
10086     VARIANT_BOOL b;
10087     HRESULT hr;
10088     DISPID did;
10089     VARIANT v;
10090     BSTR name;
10091     ULONG ret;
10092     LONG len;
10093
10094     doc = create_document(&IID_IXMLDOMDocument);
10095
10096     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
10097     EXPECT_HR(hr, S_OK);
10098
10099     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10100     EXPECT_HR(hr, S_OK);
10101
10102     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10103     EXPECT_HR(hr, S_OK);
10104     IXMLDOMSelection_Release(selection);
10105
10106     /* collection disp id */
10107     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10108     EXPECT_HR(hr, S_OK);
10109     did = 0;
10110     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10111     EXPECT_HR(hr, S_OK);
10112     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10113     len = 0;
10114     hr = IXMLDOMSelection_get_length(selection, &len);
10115     EXPECT_HR(hr, S_OK);
10116     ok(len == 1, "got %d\n", len);
10117     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10118     EXPECT_HR(hr, S_OK);
10119     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10120     IDispatchEx_Release(dispex);
10121
10122     /* IEnumVARIANT tests */
10123     enum1 = NULL;
10124     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10125     EXPECT_HR(hr, S_OK);
10126     ok(enum1 != NULL, "got %p\n", enum1);
10127     EXPECT_REF(enum1, 2);
10128
10129     enum3 = NULL;
10130     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10131     EXPECT_HR(hr, S_OK);
10132     ok(enum3 != NULL, "got %p\n", enum3);
10133     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10134     EXPECT_REF(enum1, 3);
10135     IEnumVARIANT_Release(enum3);
10136
10137     EXPECT_REF(selection, 1);
10138     EXPECT_REF(enum1, 2);
10139
10140     enum2 = NULL;
10141     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10142     EXPECT_HR(hr, S_OK);
10143     ok(enum2 != NULL, "got %p\n", enum2);
10144
10145     EXPECT_REF(selection, 2);
10146     EXPECT_REF(enum1, 2);
10147     EXPECT_REF(enum2, 1);
10148
10149     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10150
10151     selection2 = NULL;
10152     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10153     EXPECT_HR(hr, S_OK);
10154     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10155     EXPECT_REF(selection, 3);
10156     EXPECT_REF(enum1, 2);
10157
10158     IXMLDOMSelection_Release(selection2);
10159
10160     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10161     EXPECT_HR(hr, S_OK);
10162     EXPECT_REF(selection, 3);
10163     IDispatch_Release(disp);
10164
10165     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10166     EXPECT_HR(hr, S_OK);
10167     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10168     EXPECT_REF(selection, 2);
10169     EXPECT_REF(enum1, 3);
10170
10171     IEnumVARIANT_Release(enum1);
10172     IEnumVARIANT_Release(enum2);
10173
10174     enum1 = NULL;
10175     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10176     EXPECT_HR(hr, S_OK);
10177     ok(enum1 != NULL, "got %p\n", enum1);
10178     EXPECT_REF(enum1, 1);
10179     EXPECT_REF(selection, 2);
10180
10181     enum2 = NULL;
10182     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10183     EXPECT_HR(hr, S_OK);
10184     ok(enum2 != NULL, "got %p\n", enum2);
10185     EXPECT_REF(enum2, 1);
10186     EXPECT_REF(selection, 3);
10187
10188     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10189
10190     IEnumVARIANT_AddRef(enum1);
10191     EXPECT_REF(selection, 3);
10192     EXPECT_REF(enum1, 2);
10193     EXPECT_REF(enum2, 1);
10194     IEnumVARIANT_Release(enum1);
10195
10196     IEnumVARIANT_Release(enum1);
10197     IEnumVARIANT_Release(enum2);
10198
10199     EXPECT_REF(selection, 1);
10200
10201     IXMLDOMNodeList_Release(list);
10202
10203     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10204     EXPECT_HR(hr, S_OK);
10205
10206     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10207     EXPECT_HR(hr, E_NOINTERFACE);
10208
10209     IXMLDOMNodeList_Release(list);
10210
10211     /* test if IEnumVARIANT touches selection context */
10212     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
10213     EXPECT_HR(hr, S_OK);
10214
10215     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10216     EXPECT_HR(hr, S_OK);
10217
10218     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10219     EXPECT_HR(hr, S_OK);
10220
10221     len = 0;
10222     hr = IXMLDOMSelection_get_length(selection, &len);
10223     EXPECT_HR(hr, S_OK);
10224     ok(len == 4, "got %d\n", len);
10225
10226     enum1 = NULL;
10227     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10228     EXPECT_HR(hr, S_OK);
10229
10230     /* no-op if zero count */
10231     V_VT(&v) = VT_I2;
10232     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10233     EXPECT_HR(hr, S_OK);
10234     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10235
10236     /* positive count, null array pointer */
10237     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10238     EXPECT_HR(hr, E_INVALIDARG);
10239
10240     ret = 1;
10241     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10242     EXPECT_HR(hr, E_INVALIDARG);
10243     ok(ret == 0, "got %d\n", ret);
10244
10245     V_VT(&v) = VT_I2;
10246     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10247     EXPECT_HR(hr, S_OK);
10248     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10249
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_("a")), "got node name %s\n", wine_dbgstr_w(name));
10255     SysFreeString(name);
10256     IXMLDOMNode_Release(node);
10257     VariantClear(&v);
10258
10259     /* list cursor is updated */
10260     hr = IXMLDOMSelection_nextNode(selection, &node);
10261     EXPECT_HR(hr, S_OK);
10262     hr = IXMLDOMNode_get_nodeName(node, &name);
10263     EXPECT_HR(hr, S_OK);
10264     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10265     IXMLDOMNode_Release(node);
10266
10267     V_VT(&v) = VT_I2;
10268     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10269     EXPECT_HR(hr, S_OK);
10270     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10271     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10272     EXPECT_HR(hr, S_OK);
10273     hr = IXMLDOMNode_get_nodeName(node, &name);
10274     EXPECT_HR(hr, S_OK);
10275     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10276     SysFreeString(name);
10277     IXMLDOMNode_Release(node);
10278     VariantClear(&v);
10279
10280     hr = IXMLDOMSelection_nextNode(selection, &node);
10281     EXPECT_HR(hr, S_OK);
10282     hr = IXMLDOMNode_get_nodeName(node, &name);
10283     EXPECT_HR(hr, S_OK);
10284     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10285     IXMLDOMNode_Release(node);
10286
10287     IXMLDOMSelection_Release(selection);
10288     IXMLDOMNodeList_Release(list);
10289     IXMLDOMDocument_Release(doc);
10290
10291     free_bstrs();
10292 }
10293
10294 static void test_load(void)
10295 {
10296     IXMLDOMDocument *doc;
10297     IXMLDOMNodeList *list;
10298     VARIANT_BOOL b;
10299     HANDLE hfile;
10300     VARIANT src;
10301     HRESULT hr;
10302     BOOL ret;
10303     BSTR path, bstr1, bstr2;
10304     DWORD written;
10305     void* ptr;
10306
10307     /* prepare a file */
10308     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10309     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10310     if(hfile == INVALID_HANDLE_VALUE) return;
10311
10312     ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
10313     ok(ret, "WriteFile failed\n");
10314
10315     CloseHandle(hfile);
10316
10317     doc = create_document(&IID_IXMLDOMDocument);
10318
10319     path = _bstr_("test.xml");
10320
10321     /* load from path: VT_BSTR */
10322     V_VT(&src) = VT_BSTR;
10323     V_BSTR(&src) = path;
10324     hr = IXMLDOMDocument_load(doc, src, &b);
10325     EXPECT_HR(hr, S_OK);
10326     ok(b == VARIANT_TRUE, "got %d\n", b);
10327
10328     /* load from a path: VT_BSTR|VT_BYREF */
10329     V_VT(&src) = VT_BSTR | VT_BYREF;
10330     V_BSTRREF(&src) = &path;
10331     hr = IXMLDOMDocument_load(doc, src, &b);
10332     EXPECT_HR(hr, S_OK);
10333     ok(b == VARIANT_TRUE, "got %d\n", b);
10334
10335     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10336     V_VT(&src) = VT_BSTR | VT_BYREF;
10337     V_BSTRREF(&src) = NULL;
10338     hr = IXMLDOMDocument_load(doc, src, &b);
10339     EXPECT_HR(hr, E_INVALIDARG);
10340     ok(b == VARIANT_FALSE, "got %d\n", b);
10341
10342     IXMLDOMDocument_Release(doc);
10343
10344     DeleteFileA("test.xml");
10345
10346     doc = create_document(&IID_IXMLDOMDocument);
10347
10348     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10349     EXPECT_HR(hr, S_OK);
10350     ok(b == VARIANT_TRUE, "got %d\n", b);
10351
10352     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10353     EXPECT_HR(hr, S_OK);
10354     bstr1 = _bstr_(list_to_string(list));
10355
10356     hr = IXMLDOMNodeList_reset(list);
10357     EXPECT_HR(hr, S_OK);
10358
10359     IXMLDOMDocument_Release(doc);
10360
10361     doc = create_document(&IID_IXMLDOMDocument);
10362
10363     VariantInit(&src);
10364     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10365     V_VT(&src) = VT_ARRAY|VT_UI1;
10366     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10367     ptr = NULL;
10368     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10369     EXPECT_HR(hr, S_OK);
10370     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10371
10372     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10373     hr = SafeArrayUnlock(V_ARRAY(&src));
10374     EXPECT_HR(hr, S_OK);
10375
10376     hr = IXMLDOMDocument_load(doc, src, &b);
10377     EXPECT_HR(hr, S_OK);
10378     ok(b == VARIANT_TRUE, "got %d\n", b);
10379
10380     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10381     EXPECT_HR(hr, S_OK);
10382     bstr2 = _bstr_(list_to_string(list));
10383
10384     hr = IXMLDOMNodeList_reset(list);
10385     EXPECT_HR(hr, S_OK);
10386
10387     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10388        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10389
10390     IXMLDOMDocument_Release(doc);
10391     IXMLDOMNodeList_Release(list);
10392     VariantClear(&src);
10393
10394     /* UTF-16 isn't accepted */
10395     doc = create_document(&IID_IXMLDOMDocument);
10396
10397     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10398     V_VT(&src) = VT_ARRAY|VT_UI1;
10399     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10400     ptr = NULL;
10401     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10402     EXPECT_HR(hr, S_OK);
10403     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10404
10405     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10406     hr = SafeArrayUnlock(V_ARRAY(&src));
10407     EXPECT_HR(hr, S_OK);
10408
10409     hr = IXMLDOMDocument_load(doc, src, &b);
10410     todo_wine EXPECT_HR(hr, S_FALSE);
10411     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10412
10413     VariantClear(&src);
10414
10415     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10416     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10417     V_VT(&src) = VT_ARRAY|VT_UI2;
10418     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10419     ptr = NULL;
10420     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10421     EXPECT_HR(hr, S_OK);
10422     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10423
10424     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10425     hr = SafeArrayUnlock(V_ARRAY(&src));
10426     EXPECT_HR(hr, S_OK);
10427
10428     hr = IXMLDOMDocument_load(doc, src, &b);
10429     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10430     ok(b == VARIANT_FALSE, "got %d\n", b);
10431
10432     VariantClear(&src);
10433     IXMLDOMDocument_Release(doc);
10434
10435     free_bstrs();
10436 }
10437
10438 static void test_domobj_dispex(IUnknown *obj)
10439 {
10440     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10441     IDispatchEx *dispex;
10442     IUnknown *unk;
10443     DWORD props;
10444     UINT ticnt;
10445     HRESULT hr;
10446     BSTR name;
10447
10448     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10449     EXPECT_HR(hr, S_OK);
10450     if (FAILED(hr)) return;
10451
10452     ticnt = 0;
10453     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10454     EXPECT_HR(hr, S_OK);
10455     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10456
10457     name = SysAllocString(szstar);
10458     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10459     EXPECT_HR(hr, E_NOTIMPL);
10460     SysFreeString(name);
10461
10462     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10463     EXPECT_HR(hr, E_NOTIMPL);
10464
10465     props = 0;
10466     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10467     EXPECT_HR(hr, E_NOTIMPL);
10468     ok(props == 0, "expected 0 got %d\n", props);
10469
10470     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10471     EXPECT_HR(hr, E_NOTIMPL);
10472     if (SUCCEEDED(hr)) SysFreeString(name);
10473
10474     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10475     EXPECT_HR(hr, E_NOTIMPL);
10476
10477     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10478     EXPECT_HR(hr, E_NOTIMPL);
10479     if (hr == S_OK && unk) IUnknown_Release(unk);
10480
10481     IDispatchEx_Release(dispex);
10482 }
10483
10484 static void test_mxnamespacemanager(void)
10485 {
10486     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10487     IMXNamespacePrefixes *prefixes;
10488     IVBMXNamespaceManager *mgr2;
10489     IMXNamespaceManager *nsmgr;
10490     IUnknown *unk1, *unk2;
10491     WCHAR buffW[250];
10492     IDispatch *disp;
10493     IUnknown *unk;
10494     HRESULT hr;
10495     INT len;
10496
10497     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10498         &IID_IMXNamespaceManager, (void**)&nsmgr);
10499     EXPECT_HR(hr, S_OK);
10500
10501     /* IMXNamespaceManager inherits from IUnknown */
10502     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10503     EXPECT_HR(hr, S_OK);
10504     IDispatch_Release(disp);
10505
10506     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10507     EXPECT_HR(hr, S_OK);
10508
10509     EXPECT_REF(nsmgr, 2);
10510     EXPECT_REF(mgr2, 2);
10511     prefixes = NULL;
10512     hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
10513     if (hr == S_OK)
10514     {
10515         ok(prefixes != NULL, "got %p\n", prefixes);
10516         EXPECT_REF(nsmgr, 2);
10517         EXPECT_REF(mgr2, 2);
10518         EXPECT_REF(prefixes, 1);
10519
10520         IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1);
10521         IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2);
10522
10523         EXPECT_REF(mgr2, 3);
10524         EXPECT_REF(prefixes, 2);
10525
10526         IUnknown_Release(unk1);
10527         IUnknown_Release(unk2);
10528         IMXNamespacePrefixes_Release(prefixes);
10529     }
10530     IVBMXNamespaceManager_Release(mgr2);
10531
10532     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10533     EXPECT_HR(hr, S_OK);
10534
10535     /* prefix already added */
10536     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10537     EXPECT_HR(hr, S_FALSE);
10538
10539     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10540     EXPECT_HR(hr, E_INVALIDARG);
10541
10542     /* "xml" and "xmlns" are not allowed here */
10543     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10544     EXPECT_HR(hr, E_INVALIDARG);
10545
10546     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10547     EXPECT_HR(hr, E_INVALIDARG);
10548 todo_wine {
10549     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10550     EXPECT_HR(hr, E_FAIL);
10551 }
10552     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10553     EXPECT_HR(hr, E_POINTER);
10554
10555     len = -1;
10556     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10557     EXPECT_HR(hr, S_OK);
10558     ok(len == 3, "got %d\n", len);
10559
10560     len = -1;
10561     buffW[0] = 0x1;
10562     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10563     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10564     ok(len == -1, "got %d\n", len);
10565     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10566
10567     len = 10;
10568     buffW[0] = 0x1;
10569     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10570     EXPECT_HR(hr, S_OK);
10571     ok(len == 3, "got %d\n", len);
10572     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10573
10574     /* getURI */
10575     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10576     EXPECT_HR(hr, E_INVALIDARG);
10577
10578     len = -1;
10579     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10580     EXPECT_HR(hr, E_INVALIDARG);
10581     ok(len == -1, "got %d\n", len);
10582
10583     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10584     EXPECT_HR(hr, E_POINTER);
10585
10586     len = -1;
10587     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10588     EXPECT_HR(hr, S_OK);
10589     /* length of "xml" uri is constant */
10590     ok(len == strlen(xmluriA), "got %d\n", len);
10591
10592     len = 100;
10593     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10594     EXPECT_HR(hr, S_OK);
10595     ok(len == strlen(xmluriA), "got %d\n", len);
10596     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10597
10598     len = strlen(xmluriA)-1;
10599     buffW[0] = 0x1;
10600     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10601     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10602     ok(len == strlen(xmluriA)-1, "got %d\n", len);
10603     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10604
10605     /* prefix xml1 not defined */
10606     len = -1;
10607     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10608     EXPECT_HR(hr, S_FALSE);
10609     ok(len == 0, "got %d\n", len);
10610
10611     len = 100;
10612     buffW[0] = 0x1;
10613     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10614     EXPECT_HR(hr, S_FALSE);
10615     ok(buffW[0] == 0, "got %x\n", buffW[0]);
10616     ok(len == 0, "got %d\n", len);
10617
10618     /* IDispatchEx tests */
10619     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10620     EXPECT_HR(hr, S_OK);
10621     test_domobj_dispex(unk);
10622     IUnknown_Release(unk);
10623
10624     IMXNamespaceManager_Release(nsmgr);
10625
10626     /* ::getPrefix() */
10627     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10628         &IID_IMXNamespaceManager, (void**)&nsmgr);
10629     EXPECT_HR(hr, S_OK);
10630
10631     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10632     EXPECT_HR(hr, E_INVALIDARG);
10633
10634     len = -1;
10635     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10636     EXPECT_HR(hr, E_INVALIDARG);
10637     ok(len == -1, "got %d\n", len);
10638
10639     len = 100;
10640     buffW[0] = 0x1;
10641     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10642     EXPECT_HR(hr, E_FAIL);
10643     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10644     ok(len == 100, "got %d\n", len);
10645
10646     len = 0;
10647     buffW[0] = 0x1;
10648     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10649     EXPECT_HR(hr, E_FAIL);
10650     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10651     ok(len == 0, "got %d\n", len);
10652
10653     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10654     EXPECT_HR(hr, S_OK);
10655
10656     len = 100;
10657     buffW[0] = 0x1;
10658     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10659     EXPECT_HR(hr, S_OK);
10660     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10661     ok(len == 3, "got %d\n", len);
10662
10663     len = 100;
10664     buffW[0] = 0x1;
10665     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10666     EXPECT_HR(hr, S_OK);
10667     ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10668     ok(len == 3, "got %d\n", len);
10669
10670     /* with null buffer it's possible to get required length */
10671     len = 100;
10672     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10673     EXPECT_HR(hr, S_OK);
10674     ok(len == 3, "got %d\n", len);
10675
10676     len = 0;
10677     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10678     EXPECT_HR(hr, S_OK);
10679     ok(len == 3, "got %d\n", len);
10680
10681     len = 100;
10682     buffW[0] = 0x1;
10683     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10684     EXPECT_HR(hr, E_FAIL);
10685     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10686     ok(len == 100, "got %d\n", len);
10687
10688     len = 100;
10689     buffW[0] = 0x1;
10690     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10691     EXPECT_HR(hr, E_FAIL);
10692     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10693     ok(len == 100, "got %d\n", len);
10694
10695     len = 100;
10696     buffW[0] = 0x1;
10697     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10698     EXPECT_HR(hr, E_INVALIDARG);
10699     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10700     ok(len == 100, "got %d\n", len);
10701
10702     len = 100;
10703     buffW[0] = 0x1;
10704     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10705     EXPECT_HR(hr, E_INVALIDARG);
10706     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10707     ok(len == 100, "got %d\n", len);
10708
10709     len = 100;
10710     buffW[0] = 0x1;
10711     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10712     EXPECT_HR(hr, E_INVALIDARG);
10713     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10714     ok(len == 100, "got %d\n", len);
10715
10716     len = 100;
10717     buffW[0] = 0x1;
10718     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10719     EXPECT_HR(hr, E_FAIL);
10720     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10721     ok(len == 100, "got %d\n", len);
10722
10723     len = 100;
10724     buffW[0] = 0x1;
10725     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10726     EXPECT_HR(hr, E_INVALIDARG);
10727     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10728     ok(len == 100, "got %d\n", len);
10729
10730     /* declare another one, indices are shifted */
10731     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10732     EXPECT_HR(hr, S_OK);
10733
10734     len = 100;
10735     buffW[0] = 0x1;
10736     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10737     EXPECT_HR(hr, S_OK);
10738     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10739     ok(len == 3, "got %d\n", len);
10740
10741     len = 100;
10742     buffW[0] = 0x1;
10743     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10744     EXPECT_HR(hr, S_OK);
10745     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10746     ok(len == 3, "got %d\n", len);
10747
10748     len = 100;
10749     buffW[0] = 0x1;
10750     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10751     EXPECT_HR(hr, E_FAIL);
10752     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10753     ok(len == 100, "got %d\n", len);
10754
10755     len = 100;
10756     buffW[0] = 0x1;
10757     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10758     EXPECT_HR(hr, E_INVALIDARG);
10759     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10760     ok(len == 100, "got %d\n", len);
10761
10762     IMXNamespaceManager_Release(nsmgr);
10763
10764     /* push/pop tests */
10765     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10766         &IID_IMXNamespaceManager, (void**)&nsmgr);
10767     EXPECT_HR(hr, S_OK);
10768
10769     /* pop with empty stack */
10770     hr = IMXNamespaceManager_popContext(nsmgr);
10771     EXPECT_HR(hr, E_FAIL);
10772
10773     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10774     EXPECT_HR(hr, S_OK);
10775
10776     len = 100;
10777     buffW[0] = 0x1;
10778     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10779     EXPECT_HR(hr, S_OK);
10780     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10781     ok(len == 3, "got %d\n", len);
10782
10783     hr = IMXNamespaceManager_pushContext(nsmgr);
10784     EXPECT_HR(hr, S_OK);
10785
10786     len = 100;
10787     buffW[0] = 0x1;
10788     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10789     EXPECT_HR(hr, S_OK);
10790     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10791     ok(len == 3, "got %d\n", len);
10792
10793     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10794     EXPECT_HR(hr, S_OK);
10795
10796     len = 100;
10797     buffW[0] = 0x1;
10798     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10799     EXPECT_HR(hr, S_OK);
10800     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10801     ok(len == 3, "got %d\n", len);
10802
10803     hr = IMXNamespaceManager_pushContext(nsmgr);
10804     EXPECT_HR(hr, S_OK);
10805     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
10806     EXPECT_HR(hr, S_OK);
10807
10808     len = 100;
10809     buffW[0] = 0x1;
10810     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10811     EXPECT_HR(hr, S_OK);
10812     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10813     ok(len == 3, "got %d\n", len);
10814
10815     len = 100;
10816     buffW[0] = 0x1;
10817     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10818     EXPECT_HR(hr, S_OK);
10819     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10820     ok(len == 3, "got %d\n", len);
10821
10822     hr = IMXNamespaceManager_popContext(nsmgr);
10823     EXPECT_HR(hr, S_OK);
10824
10825     hr = IMXNamespaceManager_popContext(nsmgr);
10826     EXPECT_HR(hr, S_OK);
10827
10828     len = 100;
10829     buffW[0] = 0x1;
10830     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10831     EXPECT_HR(hr, E_FAIL);
10832     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10833     ok(len == 100, "got %d\n", len);
10834
10835     len = 100;
10836     buffW[0] = 0x1;
10837     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10838     EXPECT_HR(hr, S_OK);
10839     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10840     ok(len == 3, "got %d\n", len);
10841
10842     IMXNamespaceManager_Release(nsmgr);
10843
10844     free_bstrs();
10845 }
10846
10847 static void test_mxnamespacemanager_override(void)
10848 {
10849     IMXNamespaceManager *nsmgr;
10850     WCHAR buffW[250];
10851     VARIANT_BOOL b;
10852     HRESULT hr;
10853     INT len;
10854
10855     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10856         &IID_IMXNamespaceManager, (void**)&nsmgr);
10857     EXPECT_HR(hr, S_OK);
10858
10859     len = sizeof(buffW)/sizeof(WCHAR);
10860     buffW[0] = 0;
10861     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10862     EXPECT_HR(hr, S_OK);
10863     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10864
10865     len = sizeof(buffW)/sizeof(WCHAR);
10866     buffW[0] = 0;
10867     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10868     EXPECT_HR(hr, E_FAIL);
10869
10870     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10871     EXPECT_HR(hr, E_POINTER);
10872
10873     b = VARIANT_FALSE;
10874     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10875     EXPECT_HR(hr, S_OK);
10876     ok(b == VARIANT_TRUE, "got %d\n", b);
10877
10878     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10879     EXPECT_HR(hr, S_OK);
10880
10881     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10882     EXPECT_HR(hr, S_OK);
10883
10884     len = sizeof(buffW)/sizeof(WCHAR);
10885     buffW[0] = 0;
10886     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10887     EXPECT_HR(hr, S_OK);
10888     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10889
10890     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10891     EXPECT_HR(hr, S_OK);
10892
10893     len = sizeof(buffW)/sizeof(WCHAR);
10894     buffW[0] = 0;
10895     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10896     EXPECT_HR(hr, S_OK);
10897     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10898
10899     len = sizeof(buffW)/sizeof(WCHAR);
10900     buffW[0] = 0;
10901     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10902     EXPECT_HR(hr, S_OK);
10903     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10904
10905     len = sizeof(buffW)/sizeof(WCHAR);
10906     buffW[0] = 0;
10907     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10908     EXPECT_HR(hr, S_OK);
10909     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10910
10911     /* new prefix placed at index 1 always */
10912     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10913     EXPECT_HR(hr, S_OK);
10914
10915     len = sizeof(buffW)/sizeof(WCHAR);
10916     buffW[0] = 0;
10917     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10918     EXPECT_HR(hr, S_OK);
10919     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10920
10921     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10922     todo_wine EXPECT_HR(hr, E_FAIL);
10923
10924     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10925     EXPECT_HR(hr, E_FAIL);
10926
10927     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10928     EXPECT_HR(hr, E_FAIL);
10929
10930     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10931     EXPECT_HR(hr, S_OK);
10932
10933     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10934     EXPECT_HR(hr, S_FALSE);
10935
10936     len = sizeof(buffW)/sizeof(WCHAR);
10937     buffW[0] = 0;
10938     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10939     EXPECT_HR(hr, S_OK);
10940     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10941
10942     len = sizeof(buffW)/sizeof(WCHAR);
10943     buffW[0] = 0;
10944     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10945     EXPECT_HR(hr, S_OK);
10946     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10947
10948     IMXNamespaceManager_Release(nsmgr);
10949
10950     free_bstrs();
10951 }
10952
10953 static const DOMNodeType nodetypes_test[] =
10954 {
10955     NODE_ELEMENT,
10956     NODE_ATTRIBUTE,
10957     NODE_TEXT,
10958     NODE_CDATA_SECTION,
10959     NODE_ENTITY_REFERENCE,
10960     NODE_PROCESSING_INSTRUCTION,
10961     NODE_COMMENT,
10962     NODE_DOCUMENT_FRAGMENT,
10963     NODE_INVALID
10964 };
10965
10966 static void test_dispex(void)
10967 {
10968     const DOMNodeType *type = nodetypes_test;
10969     IXMLDOMImplementation *impl;
10970     IXMLDOMNodeList *node_list;
10971     IXMLDOMParseError *error;
10972     IXMLDOMNamedNodeMap *map;
10973     IXSLProcessor *processor;
10974     IXSLTemplate *template;
10975     IXMLDOMDocument *doc;
10976     IXMLHTTPRequest *req;
10977     IXMLDOMElement *elem;
10978     IDispatchEx *dispex;
10979     IXMLDOMNode *node;
10980     VARIANT_BOOL b;
10981     IUnknown *unk;
10982     HRESULT hr;
10983     DISPID did;
10984
10985     doc = create_document(&IID_IXMLDOMDocument);
10986
10987     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10988     test_domobj_dispex(unk);
10989     IUnknown_Release(unk);
10990
10991     for(; *type != NODE_INVALID; type++)
10992     {
10993         IXMLDOMNode *node;
10994         VARIANT v;
10995
10996         V_VT(&v) = VT_I2;
10997         V_I2(&v) = *type;
10998
10999         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
11000         ok(hr == S_OK, "failed to create node type %d\n", *type);
11001
11002         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
11003
11004         test_domobj_dispex(unk);
11005         IUnknown_Release(unk);
11006         IXMLDOMNode_Release(node);
11007     }
11008
11009     /* IXMLDOMNodeList */
11010     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
11011     EXPECT_HR(hr, S_OK);
11012     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11013     test_domobj_dispex(unk);
11014     IUnknown_Release(unk);
11015     IXMLDOMNodeList_Release(node_list);
11016
11017     /* IXMLDOMNodeList for children list */
11018     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
11019     EXPECT_HR(hr, S_OK);
11020     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11021     test_domobj_dispex(unk);
11022     IUnknown_Release(unk);
11023
11024     /* collection dispex test, empty collection */
11025     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
11026     EXPECT_HR(hr, S_OK);
11027     did = 0;
11028     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11029     EXPECT_HR(hr, S_OK);
11030     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11031     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11032     EXPECT_HR(hr, S_OK);
11033     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11034     IDispatchEx_Release(dispex);
11035
11036     IXMLDOMNodeList_Release(node_list);
11037
11038     /* IXMLDOMParseError */
11039     hr = IXMLDOMDocument_get_parseError(doc, &error);
11040     EXPECT_HR(hr, S_OK);
11041     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11042     test_domobj_dispex(unk);
11043     IUnknown_Release(unk);
11044     IXMLDOMParseError_Release(error);
11045
11046     /* IXMLDOMNamedNodeMap */
11047     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
11048     EXPECT_HR(hr, S_OK);
11049
11050     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11051     EXPECT_HR(hr, S_OK);
11052     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11053     EXPECT_HR(hr, S_OK);
11054     IXMLDOMNodeList_Release(node_list);
11055
11056     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11057     EXPECT_HR(hr, S_OK);
11058     IXMLDOMNode_Release(node);
11059     hr = IXMLDOMElement_get_attributes(elem, &map);
11060     EXPECT_HR(hr, S_OK);
11061     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11062     test_domobj_dispex(unk);
11063     IUnknown_Release(unk);
11064     /* collection dispex test */
11065     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11066     EXPECT_HR(hr, S_OK);
11067     did = 0;
11068     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11069     EXPECT_HR(hr, S_OK);
11070     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11071     IDispatchEx_Release(dispex);
11072
11073     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11074     EXPECT_HR(hr, S_OK);
11075     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11076     EXPECT_HR(hr, S_OK);
11077     IXMLDOMNodeList_Release(node_list);
11078     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11079     EXPECT_HR(hr, S_OK);
11080     IXMLDOMNode_Release(node);
11081     hr = IXMLDOMElement_get_attributes(elem, &map);
11082     EXPECT_HR(hr, S_OK);
11083     /* collection dispex test, empty collection */
11084     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11085     EXPECT_HR(hr, S_OK);
11086     did = 0;
11087     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11088     EXPECT_HR(hr, S_OK);
11089     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11090     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11091     EXPECT_HR(hr, S_OK);
11092     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11093     IDispatchEx_Release(dispex);
11094
11095     IXMLDOMNamedNodeMap_Release(map);
11096     IXMLDOMElement_Release(elem);
11097
11098     /* IXMLDOMImplementation */
11099     hr = IXMLDOMDocument_get_implementation(doc, &impl);
11100     EXPECT_HR(hr, S_OK);
11101
11102     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11103     EXPECT_HR(hr, S_OK);
11104     IDispatchEx_Release(dispex);
11105     IXMLDOMImplementation_Release(impl);
11106
11107     IXMLDOMDocument_Release(doc);
11108
11109     /* IXMLHTTPRequest */
11110     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11111         &IID_IXMLHttpRequest, (void**)&req);
11112     if (hr == S_OK)
11113     {
11114         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11115         EXPECT_HR(hr, E_NOINTERFACE);
11116         IXMLHTTPRequest_Release(req);
11117     }
11118
11119     /* IXSLTemplate */
11120     template = create_xsltemplate(&IID_IXSLTemplate);
11121     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11122     EXPECT_HR(hr, S_OK);
11123     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11124     EXPECT_HR(hr, S_OK);
11125     test_domobj_dispex(unk);
11126     IUnknown_Release(unk);
11127     IDispatchEx_Release(dispex);
11128
11129     /* IXSLProcessor */
11130     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11131     EXPECT_HR(hr, S_OK);
11132     b = VARIANT_FALSE;
11133     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11134     EXPECT_HR(hr, S_OK);
11135     ok(b == VARIANT_TRUE, "got %d\n", b);
11136
11137     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11138     EXPECT_HR(hr, S_OK);
11139     IXMLDOMDocument_Release(doc);
11140
11141     hr = IXSLTemplate_createProcessor(template, &processor);
11142     EXPECT_HR(hr, S_OK);
11143     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11144     EXPECT_HR(hr, S_OK);
11145     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11146     EXPECT_HR(hr, S_OK);
11147     test_domobj_dispex(unk);
11148     IUnknown_Release(unk);
11149     IDispatchEx_Release(dispex);
11150
11151     IXSLProcessor_Release(processor);
11152     IXSLTemplate_Release(template);
11153
11154     free_bstrs();
11155 }
11156
11157 static void test_parseerror(void)
11158 {
11159     IXMLDOMParseError2 *error2;
11160     IXMLDOMParseError *error;
11161     IXMLDOMDocument *doc;
11162     HRESULT hr;
11163
11164     doc = create_document(&IID_IXMLDOMDocument);
11165
11166     hr = IXMLDOMDocument_get_parseError(doc, &error);
11167     EXPECT_HR(hr, S_OK);
11168
11169     hr = IXMLDOMParseError_get_line(error, NULL);
11170     EXPECT_HR(hr, E_INVALIDARG);
11171
11172     hr = IXMLDOMParseError_get_srcText(error, NULL);
11173     EXPECT_HR(hr, E_INVALIDARG);
11174
11175     hr = IXMLDOMParseError_get_linepos(error, NULL);
11176     EXPECT_HR(hr, E_INVALIDARG);
11177
11178     IXMLDOMParseError_Release(error);
11179     IXMLDOMDocument_Release(doc);
11180
11181     doc = create_document_version(60, &IID_IXMLDOMDocument);
11182     if (!doc) return;
11183     hr = IXMLDOMDocument_get_parseError(doc, &error);
11184     EXPECT_HR(hr, S_OK);
11185     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11186     EXPECT_HR(hr, S_OK);
11187     IXMLDOMParseError2_Release(error2);
11188     IXMLDOMParseError_Release(error);
11189     IXMLDOMDocument_Release(doc);
11190 }
11191
11192 static void test_getAttributeNode(void)
11193 {
11194     IXMLDOMAttribute *attr;
11195     IXMLDOMDocument *doc;
11196     IXMLDOMElement *elem;
11197     VARIANT_BOOL v;
11198     HRESULT hr;
11199     BSTR str;
11200
11201     doc = create_document(&IID_IXMLDOMDocument);
11202
11203     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11204     EXPECT_HR(hr, S_OK);
11205
11206     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11207     EXPECT_HR(hr, S_OK);
11208
11209     str = SysAllocString(nonexistent_fileW);
11210     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11211     EXPECT_HR(hr, E_FAIL);
11212
11213     attr = (IXMLDOMAttribute*)0xdeadbeef;
11214     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11215     EXPECT_HR(hr, E_FAIL);
11216     ok(attr == NULL, "got %p\n", attr);
11217     SysFreeString(str);
11218
11219     str = SysAllocString(nonexistent_attrW);
11220     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11221     EXPECT_HR(hr, S_FALSE);
11222
11223     attr = (IXMLDOMAttribute*)0xdeadbeef;
11224     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11225     EXPECT_HR(hr, S_FALSE);
11226     ok(attr == NULL, "got %p\n", attr);
11227     SysFreeString(str);
11228
11229     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11230     EXPECT_HR(hr, S_OK);
11231     IXMLDOMAttribute_Release(attr);
11232
11233     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11234     EXPECT_HR(hr, S_FALSE);
11235
11236     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11237     EXPECT_HR(hr, S_OK);
11238     IXMLDOMAttribute_Release(attr);
11239
11240     IXMLDOMElement_Release(elem);
11241     IXMLDOMDocument_Release(doc);
11242     free_bstrs();
11243 }
11244
11245 typedef struct {
11246     DOMNodeType type;
11247     const char *name;
11248     REFIID iids[3];
11249 } supporterror_t;
11250
11251 static const supporterror_t supporterror_test[] = {
11252     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11253     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11254     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11255     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11256     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11257     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11258     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11259     { NODE_INVALID }
11260 };
11261
11262 static void test_supporterrorinfo(void)
11263 {
11264     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11265                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11266     const supporterror_t *ptr = supporterror_test;
11267     ISupportErrorInfo *errorinfo, *info2;
11268     IXMLDOMNamedNodeMap *map, *map2;
11269     IXMLDOMDocument *doc;
11270     IXMLDOMElement *elem;
11271     VARIANT_BOOL b;
11272     IUnknown *unk;
11273     REFIID *iid;
11274     void *dummy;
11275     HRESULT hr;
11276
11277     doc = create_document_version(60, &IID_IXMLDOMDocument3);
11278     if (!doc) return;
11279
11280     EXPECT_REF(doc, 1);
11281     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11282     EXPECT_HR(hr, S_OK);
11283     EXPECT_REF(doc, 1);
11284     ISupportErrorInfo_AddRef(errorinfo);
11285     EXPECT_REF(errorinfo, 2);
11286     EXPECT_REF(doc, 1);
11287     ISupportErrorInfo_Release(errorinfo);
11288
11289     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11290     EXPECT_HR(hr, S_OK);
11291     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11292
11293     /* error interface can't be queried back for DOM interface */
11294     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11295     EXPECT_HR(hr, E_NOINTERFACE);
11296     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11297     EXPECT_HR(hr, E_NOINTERFACE);
11298
11299     ISupportErrorInfo_Release(info2);
11300
11301     iid = iids;
11302     while (*iid)
11303     {
11304         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11305         EXPECT_HR(hr, S_OK);
11306         if (hr == S_OK)
11307         {
11308             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11309             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11310             IUnknown_Release(unk);
11311         }
11312
11313         iid++;
11314     }
11315
11316     ISupportErrorInfo_Release(errorinfo);
11317
11318     while (ptr->type != NODE_INVALID)
11319     {
11320         IXMLDOMNode *node;
11321         VARIANT type;
11322
11323         V_VT(&type) = VT_I1;
11324         V_I1(&type) = ptr->type;
11325
11326         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11327         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11328
11329         EXPECT_REF(node, 1);
11330         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11331         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11332         EXPECT_REF(node, 1);
11333
11334         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11335         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11336
11337         iid = ptr->iids;
11338
11339         while (*iid)
11340         {
11341             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11342             if (hr == S_OK)
11343             {
11344                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11345                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11346                 IUnknown_Release(unk);
11347             }
11348
11349             iid++;
11350         }
11351
11352         ISupportErrorInfo_Release(errorinfo);
11353         IXMLDOMNode_Release(node);
11354         ptr++;
11355     }
11356
11357     /* IXMLDOMNamedNodeMap */
11358     b = VARIANT_FALSE;
11359     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11360     EXPECT_HR(hr, S_OK);
11361     ok(b == VARIANT_TRUE, "got %d\n", b);
11362
11363     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11364     EXPECT_HR(hr, S_OK);
11365
11366     hr = IXMLDOMElement_get_attributes(elem, &map);
11367     EXPECT_HR(hr, S_OK);
11368
11369     EXPECT_REF(map, 1);
11370     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11371     EXPECT_HR(hr, S_OK);
11372     EXPECT_REF(map, 2);
11373
11374     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11375     EXPECT_HR(hr, S_OK);
11376
11377     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11378     EXPECT_HR(hr, S_OK);
11379     ok(map == map2, "got %p\n", map2);
11380     IXMLDOMNamedNodeMap_Release(map2);
11381
11382     EXPECT_REF(errorinfo, 2);
11383     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11384     EXPECT_HR(hr, S_OK);
11385     EXPECT_REF(errorinfo, 3);
11386     EXPECT_REF(map, 3);
11387     IUnknown_Release(unk);
11388
11389     ISupportErrorInfo_Release(errorinfo);
11390     IXMLDOMNamedNodeMap_Release(map);
11391     IXMLDOMElement_Release(elem);
11392
11393     IXMLDOMDocument_Release(doc);
11394     free_bstrs();
11395 }
11396
11397 typedef struct {
11398     DOMNodeType type;
11399     const char *name;
11400     const char *put_content;
11401     HRESULT put_hr;
11402     VARTYPE get_vt;
11403     HRESULT get_hr;
11404 } node_value_t;
11405
11406 static const node_value_t nodevalue_test[] = {
11407     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11408     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11409     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11410     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11411     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11412     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11413     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11414     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11415     { NODE_INVALID }
11416 };
11417
11418 static void test_nodeValue(void)
11419 {
11420     const node_value_t *ptr = nodevalue_test;
11421     IXMLDOMDocument *doc;
11422     HRESULT hr;
11423
11424     doc = create_document(&IID_IXMLDOMDocument);
11425     if (!doc) return;
11426
11427     while (ptr->type != NODE_INVALID)
11428     {
11429         IXMLDOMNode *node;
11430         VARIANT v;
11431
11432         V_VT(&v) = VT_I2;
11433         V_I2(&v) = ptr->type;
11434
11435         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11436         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11437
11438         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11439         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11440
11441         V_VT(&v) = VT_BSTR;
11442         V_BSTR(&v) = _bstr_(ptr->put_content);
11443         hr = IXMLDOMNode_put_nodeValue(node, v);
11444         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11445
11446         V_VT(&v) = VT_EMPTY;
11447         hr = IXMLDOMNode_get_nodeValue(node, &v);
11448         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11449         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11450         if (hr == S_OK)
11451             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11452                 wine_dbgstr_w(V_BSTR(&v)));
11453         VariantClear(&v);
11454
11455         IXMLDOMNode_Release(node);
11456
11457         ptr++;
11458     }
11459
11460     IXMLDOMDocument_Release(doc);
11461 }
11462
11463 static const char namespacesA[] =
11464 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11465 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11466 "     <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11467 "     <ns1:elem3/>"
11468 "     <ns1:elem4/>"
11469 "     <elem5 xmlns=\"http://blahblah.org\"/>"
11470 "     <ns1:elem6>true</ns1:elem6>"
11471 "   </ns1:elem1>";
11472
11473 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11474 static const char xsd_schema1_xml[] =
11475 "<?xml version='1.0'?>"
11476 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11477 "            targetNamespace='x-schema:test1.xsd'>"
11478 "   <element name='root'>"
11479 "       <complexType>"
11480 "           <sequence maxOccurs='unbounded'>"
11481 "               <any/>"
11482 "           </sequence>"
11483 "       </complexType>"
11484 "   </element>"
11485 "</schema>";
11486
11487 static void test_get_namespaces(void)
11488 {
11489     IXMLDOMSchemaCollection *collection, *collection2;
11490     IXMLDOMDocument2 *doc, *doc2;
11491     IEnumVARIANT *enumv;
11492     IXMLDOMNode *node;
11493     VARIANT_BOOL b;
11494     HRESULT hr;
11495     VARIANT v;
11496     LONG len;
11497     BSTR s;
11498
11499     doc = create_document(&IID_IXMLDOMDocument2);
11500     if (!doc) return;
11501
11502     /* null pointer */
11503     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11504     EXPECT_HR(hr, E_POINTER);
11505
11506     /* no document loaded */
11507     collection = (void*)0xdeadbeef;
11508     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11509     EXPECT_HR(hr, S_OK);
11510     if (hr != S_OK)
11511     {
11512         IXMLDOMDocument_Release(doc);
11513         return;
11514     }
11515     EXPECT_REF(collection, 2);
11516
11517     collection2 = (void*)0xdeadbeef;
11518     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11519     EXPECT_HR(hr, S_OK);
11520     ok(collection == collection2, "got %p\n", collection2);
11521     EXPECT_REF(collection, 3);
11522     IXMLDOMSchemaCollection_Release(collection);
11523
11524     len = -1;
11525     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11526     EXPECT_HR(hr, S_OK);
11527     ok(len == 0, "got %d\n", len);
11528     IXMLDOMSchemaCollection_Release(collection);
11529
11530     /* now with document */
11531     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11532     EXPECT_HR(hr, S_OK);
11533
11534     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11535     EXPECT_HR(hr, S_OK);
11536
11537     len = -1;
11538     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11539     EXPECT_HR(hr, S_OK);
11540     ok(len == 2, "got %d\n", len);
11541
11542     /* try to lookup some uris */
11543     node = (void*)0xdeadbeef;
11544     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11545     EXPECT_HR(hr, S_OK);
11546     ok(node == NULL, "got %p\n", node);
11547
11548     node = (void*)0xdeadbeef;
11549     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11550     EXPECT_HR(hr, S_OK);
11551     ok(node == NULL, "got %p\n", node);
11552
11553     /* load schema and try to add it */
11554     doc2 = create_document(&IID_IXMLDOMDocument2);
11555     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11556     EXPECT_HR(hr, S_OK);
11557
11558     V_VT(&v) = VT_DISPATCH;
11559     V_DISPATCH(&v) = (IDispatch*)doc2;
11560     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11561     EXPECT_HR(hr, E_FAIL);
11562
11563     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11564     EXPECT_HR(hr, S_OK);
11565     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11566     SysFreeString(s);
11567
11568     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11569     EXPECT_HR(hr, S_OK);
11570     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11571     SysFreeString(s);
11572
11573     s = (void*)0xdeadbeef;
11574     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11575     EXPECT_HR(hr, E_FAIL);
11576     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11577
11578     /* enumerate */
11579     enumv = (void*)0xdeadbeef;
11580     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11581 todo_wine
11582     EXPECT_HR(hr, S_OK);
11583     if (hr == S_OK)
11584     {
11585         ok(enumv != NULL, "got %p\n", enumv);
11586
11587         V_VT(&v) = VT_EMPTY;
11588         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11589         EXPECT_HR(hr, S_OK);
11590         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11591         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11592         VariantClear(&v);
11593
11594         V_VT(&v) = VT_EMPTY;
11595         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11596         EXPECT_HR(hr, S_OK);
11597         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11598         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11599         VariantClear(&v);
11600
11601         V_VT(&v) = VT_NULL;
11602         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11603         EXPECT_HR(hr, S_FALSE);
11604         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11605
11606         IEnumVARIANT_Release(enumv);
11607     }
11608     IXMLDOMSchemaCollection_Release(collection);
11609
11610     IXMLDOMDocument2_Release(doc);
11611
11612     /* now with CLSID_DOMDocument60 */
11613     doc = create_document_version(60, &IID_IXMLDOMDocument2);
11614     if (!doc) return;
11615
11616     /* null pointer */
11617     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11618     EXPECT_HR(hr, E_POINTER);
11619
11620     /* no document loaded */
11621     collection = (void*)0xdeadbeef;
11622     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11623     EXPECT_HR(hr, S_OK);
11624     if (hr != S_OK)
11625     {
11626         IXMLDOMDocument_Release(doc);
11627         return;
11628     }
11629     EXPECT_REF(collection, 2);
11630
11631     collection2 = (void*)0xdeadbeef;
11632     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11633     EXPECT_HR(hr, S_OK);
11634     ok(collection == collection2, "got %p\n", collection2);
11635     EXPECT_REF(collection, 3);
11636     IXMLDOMSchemaCollection_Release(collection);
11637
11638     len = -1;
11639     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11640     EXPECT_HR(hr, S_OK);
11641     ok(len == 0, "got %d\n", len);
11642     IXMLDOMSchemaCollection_Release(collection);
11643
11644     /* now with document */
11645     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11646     EXPECT_HR(hr, S_OK);
11647
11648     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11649     EXPECT_HR(hr, S_OK);
11650
11651     len = -1;
11652     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11653     EXPECT_HR(hr, S_OK);
11654     ok(len == 2, "got %d\n", len);
11655
11656     /* try to lookup some uris */
11657     node = (void*)0xdeadbeef;
11658     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11659     EXPECT_HR(hr, E_NOTIMPL);
11660     ok(node == (void*)0xdeadbeef, "got %p\n", node);
11661
11662     /* load schema and try to add it */
11663     doc2 = create_document(&IID_IXMLDOMDocument2);
11664     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11665     EXPECT_HR(hr, S_OK);
11666
11667     V_VT(&v) = VT_DISPATCH;
11668     V_DISPATCH(&v) = (IDispatch*)doc2;
11669     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11670     EXPECT_HR(hr, E_FAIL);
11671     IXMLDOMSchemaCollection_Release(doc2);
11672
11673     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11674     EXPECT_HR(hr, S_OK);
11675     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11676     SysFreeString(s);
11677
11678     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11679     EXPECT_HR(hr, S_OK);
11680     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11681     SysFreeString(s);
11682
11683     s = (void*)0xdeadbeef;
11684     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11685     EXPECT_HR(hr, E_FAIL);
11686     ok(s == (void*)0xdeadbeef, "got %p\n", s);
11687
11688     /* enumerate */
11689     enumv = (void*)0xdeadbeef;
11690     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11691 todo_wine
11692     EXPECT_HR(hr, S_OK);
11693     if (hr == S_OK)
11694     {
11695         ok(enumv != NULL, "got %p\n", enumv);
11696
11697         V_VT(&v) = VT_EMPTY;
11698         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11699         EXPECT_HR(hr, S_OK);
11700         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11701         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11702         VariantClear(&v);
11703
11704         V_VT(&v) = VT_EMPTY;
11705         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11706         EXPECT_HR(hr, S_OK);
11707         ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11708         ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11709         VariantClear(&v);
11710
11711         V_VT(&v) = VT_NULL;
11712         hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11713         EXPECT_HR(hr, S_FALSE);
11714         ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11715
11716         IEnumVARIANT_Release(enumv);
11717     }
11718     IXMLDOMSchemaCollection_Release(collection);
11719     IXMLDOMDocument2_Release(doc);
11720     free_bstrs();
11721 }
11722
11723 static DOMNodeType put_data_types[] = {
11724     NODE_TEXT,
11725     NODE_CDATA_SECTION,
11726     NODE_PROCESSING_INSTRUCTION,
11727     NODE_COMMENT,
11728     NODE_INVALID
11729 };
11730
11731 static void test_put_data(void)
11732 {
11733     static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0};
11734     WCHAR buff[100], *data;
11735     IXMLDOMDocument *doc;
11736     DOMNodeType *type;
11737     BSTR get_data;
11738     HRESULT hr;
11739
11740     doc = create_document(&IID_IXMLDOMDocument);
11741     if (!doc) return;
11742
11743     memcpy(&buff[2], test_data, sizeof(test_data));
11744     /* just a big length */
11745     *(DWORD*)buff = 0xf0f0;
11746     data = &buff[2];
11747
11748     type = put_data_types;
11749     while (*type != NODE_INVALID)
11750     {
11751        IXMLDOMNode *node;
11752        VARIANT v;
11753
11754        V_VT(&v) = VT_I2;
11755        V_I2(&v) = *type;
11756
11757        hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
11758        EXPECT_HR(hr, S_OK);
11759
11760        /* put_data() is interface-specific */
11761        switch (*type)
11762        {
11763            case NODE_TEXT:
11764            {
11765               IXMLDOMText *text;
11766
11767               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
11768               EXPECT_HR(hr, S_OK);
11769               hr = IXMLDOMText_put_data(text, data);
11770               EXPECT_HR(hr, S_OK);
11771
11772               hr = IXMLDOMText_get_data(text, &get_data);
11773               EXPECT_HR(hr, S_OK);
11774
11775               IXMLDOMText_Release(text);
11776               break;
11777            }
11778            case NODE_CDATA_SECTION:
11779            {
11780               IXMLDOMCDATASection *cdata;
11781
11782               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
11783               EXPECT_HR(hr, S_OK);
11784               hr = IXMLDOMCDATASection_put_data(cdata, data);
11785               EXPECT_HR(hr, S_OK);
11786
11787               hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
11788               EXPECT_HR(hr, S_OK);
11789
11790               IXMLDOMCDATASection_Release(cdata);
11791               break;
11792            }
11793            case NODE_PROCESSING_INSTRUCTION:
11794            {
11795               IXMLDOMProcessingInstruction *pi;
11796
11797               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
11798               EXPECT_HR(hr, S_OK);
11799               hr = IXMLDOMProcessingInstruction_put_data(pi, data);
11800               EXPECT_HR(hr, S_OK);
11801
11802               hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
11803               EXPECT_HR(hr, S_OK);
11804
11805               IXMLDOMProcessingInstruction_Release(pi);
11806               break;
11807            }
11808            case NODE_COMMENT:
11809            {
11810               IXMLDOMComment *comment;
11811
11812               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
11813               EXPECT_HR(hr, S_OK);
11814               hr = IXMLDOMComment_put_data(comment, data);
11815               EXPECT_HR(hr, S_OK);
11816
11817               hr = IXMLDOMComment_get_data(comment, &get_data);
11818               EXPECT_HR(hr, S_OK);
11819
11820               IXMLDOMComment_Release(comment);
11821               break;
11822            }
11823            default:
11824               break;
11825        }
11826
11827        /* compare */
11828        ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
11829            wine_dbgstr_w(data));
11830        SysFreeString(get_data);
11831
11832        IXMLDOMNode_Release(node);
11833        type++;
11834     }
11835
11836     IXMLDOMDocument_Release(doc);
11837     free_bstrs();
11838 }
11839
11840 START_TEST(domdoc)
11841 {
11842     IXMLDOMDocument *doc;
11843     IUnknown *unk;
11844     HRESULT hr;
11845
11846     hr = CoInitialize( NULL );
11847     ok( hr == S_OK, "failed to init com\n");
11848     if (hr != S_OK) return;
11849
11850     test_XMLHTTP();
11851
11852     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
11853     if (hr != S_OK)
11854     {
11855         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
11856         return;
11857     }
11858
11859     IXMLDOMDocument_Release(doc);
11860
11861     test_domdoc();
11862     test_persiststreaminit();
11863     test_domnode();
11864     test_refs();
11865     test_create();
11866     test_getElementsByTagName();
11867     test_get_text();
11868     test_get_childNodes();
11869     test_get_firstChild();
11870     test_get_lastChild();
11871     test_removeChild();
11872     test_replaceChild();
11873     test_removeNamedItem();
11874     test_IXMLDOMDocument2();
11875     test_whitespace();
11876     test_XPath();
11877     test_XSLPattern();
11878     test_cloneNode();
11879     test_xmlTypes();
11880     test_save();
11881     test_testTransforms();
11882     test_namespaces_basic();
11883     test_namespaces_change();
11884     test_FormattingXML();
11885     test_nodeTypedValue();
11886     test_TransformWithLoadingLocalFile();
11887     test_put_nodeValue();
11888     test_document_IObjectSafety();
11889     test_splitText();
11890     test_getQualifiedItem();
11891     test_removeQualifiedItem();
11892     test_get_ownerDocument();
11893     test_setAttributeNode();
11894     test_put_dataType();
11895     test_createNode();
11896     test_get_prefix();
11897     test_default_properties();
11898     test_selectSingleNode();
11899     test_events();
11900     test_createProcessingInstruction();
11901     test_put_nodeTypedValue();
11902     test_get_xml();
11903     test_insertBefore();
11904     test_appendChild();
11905     test_get_doctype();
11906     test_get_tagName();
11907     test_get_dataType();
11908     test_get_nodeTypeString();
11909     test_get_attributes();
11910     test_selection();
11911     test_load();
11912     test_dispex();
11913     test_parseerror();
11914     test_getAttributeNode();
11915     test_supporterrorinfo();
11916     test_nodeValue();
11917     test_get_namespaces();
11918     test_put_data();
11919
11920     test_xsltemplate();
11921
11922     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11923         &IID_IMXNamespaceManager, (void**)&unk);
11924     if (hr == S_OK)
11925     {
11926         test_mxnamespacemanager();
11927         test_mxnamespacemanager_override();
11928
11929         IUnknown_Release(unk);
11930     }
11931     else
11932         win_skip("MXNamespaceManager is not available\n");
11933
11934     CoUninitialize();
11935 }