uxtheme: Remove unused variable.
[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 /* IStream */
1292 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
1293 {
1294     *ppvObject = NULL;
1295
1296     if (IsEqualGUID(riid, &IID_IStream) ||
1297         IsEqualGUID(riid, &IID_IUnknown))
1298         *ppvObject = iface;
1299     else
1300         return E_NOINTERFACE;
1301
1302     return S_OK;
1303 }
1304
1305 static ULONG WINAPI istream_AddRef(IStream *iface)
1306 {
1307     return 2;
1308 }
1309
1310 static ULONG WINAPI istream_Release(IStream *iface)
1311 {
1312     return 1;
1313 }
1314
1315 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread)
1316 {
1317     ok(0, "unexpected call\n");
1318     return E_NOTIMPL;
1319 }
1320
1321 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
1322 {
1323     *written = len/2;
1324     return S_OK;
1325 }
1326
1327 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
1328 {
1329     ok(0, "unexpected call\n");
1330     return E_NOTIMPL;
1331 }
1332
1333 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size)
1334 {
1335     ok(0, "unexpected call\n");
1336     return E_NOTIMPL;
1337 }
1338
1339 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len,
1340         ULARGE_INTEGER *pread, ULARGE_INTEGER *written)
1341 {
1342     ok(0, "unexpected call\n");
1343     return E_NOTIMPL;
1344 }
1345
1346 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags)
1347 {
1348     ok(0, "unexpected call\n");
1349     return E_NOTIMPL;
1350 }
1351
1352 static HRESULT WINAPI istream_Revert(IStream *iface)
1353 {
1354     ok(0, "unexpected call\n");
1355     return E_NOTIMPL;
1356 }
1357
1358 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
1359         ULARGE_INTEGER len, DWORD locktype)
1360 {
1361     ok(0, "unexpected call\n");
1362     return E_NOTIMPL;
1363 }
1364
1365 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
1366         ULARGE_INTEGER len, DWORD locktype)
1367 {
1368     ok(0, "unexpected call\n");
1369     return E_NOTIMPL;
1370 }
1371
1372 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
1373 {
1374     ok(0, "unexpected call\n");
1375     return E_NOTIMPL;
1376 }
1377
1378 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream)
1379 {
1380     ok(0, "unexpected call\n");
1381     return E_NOTIMPL;
1382 }
1383
1384 static const IStreamVtbl StreamVtbl = {
1385     istream_QueryInterface,
1386     istream_AddRef,
1387     istream_Release,
1388     istream_Read,
1389     istream_Write,
1390     istream_Seek,
1391     istream_SetSize,
1392     istream_CopyTo,
1393     istream_Commit,
1394     istream_Revert,
1395     istream_LockRegion,
1396     istream_UnlockRegion,
1397     istream_Stat,
1398     istream_Clone
1399 };
1400
1401 static IStream savestream = { &StreamVtbl };
1402
1403 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
1404 static void _expect_children(IXMLDOMNode *node, int line)
1405 {
1406     VARIANT_BOOL b;
1407     HRESULT hr;
1408
1409     b = VARIANT_FALSE;
1410     hr = IXMLDOMNode_hasChildNodes(node, &b);
1411     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
1412     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
1413 }
1414
1415 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
1416 static void _expect_no_children(IXMLDOMNode *node, int line)
1417 {
1418     VARIANT_BOOL b;
1419     HRESULT hr;
1420
1421     b = VARIANT_TRUE;
1422     hr = IXMLDOMNode_hasChildNodes(node, &b);
1423     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
1424     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
1425 }
1426
1427 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
1428 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1429 {
1430     ULONG rc = IUnknown_AddRef(obj);
1431     IUnknown_Release(obj);
1432     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
1433 }
1434
1435 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
1436 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
1437 {
1438     LONG length;
1439     HRESULT hr;
1440
1441     length = 0;
1442     hr = IXMLDOMNodeList_get_length(list, &length);
1443     ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
1444     ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
1445 }
1446
1447 #define EXPECT_HR(hr,hr_exp) \
1448     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
1449
1450 static const WCHAR szEmpty[] = { 0 };
1451 static const WCHAR szIncomplete[] = {
1452     '<','?','x','m','l',' ',
1453     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
1454 };
1455 static const WCHAR szComplete1[] = {
1456     '<','?','x','m','l',' ',
1457     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1458     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1459 };
1460 static const WCHAR szComplete2[] = {
1461     '<','?','x','m','l',' ',
1462     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1463     '<','o','>','<','/','o','>','\n',0
1464 };
1465 static const WCHAR szComplete3[] = {
1466     '<','?','x','m','l',' ',
1467     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
1468     '<','a','>','<','/','a','>','\n',0
1469 };
1470 static const char complete4A[] =
1471     "<?xml version=\'1.0\'?>\n"
1472     "<lc dl=\'str1\'>\n"
1473         "<bs vr=\'str2\' sz=\'1234\'>"
1474             "fn1.txt\n"
1475         "</bs>\n"
1476         "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
1477             "fn2.txt\n"
1478         "</pr>\n"
1479         "<empty></empty>\n"
1480         "<fo>\n"
1481             "<ba>\n"
1482                 "f1\n"
1483             "</ba>\n"
1484         "</fo>\n"
1485     "</lc>\n";
1486
1487 static const WCHAR szComplete5[] = {
1488     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
1489     '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','"',
1490     ' ','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','"','>',
1491         '<','S',':','s','c','o','p','e','>',
1492             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
1493         '<','/','S',':','s','c','o','p','e','>',
1494         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1495             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
1496             'c','o','m','p','u','t','e','r',
1497         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
1498     '<','/','S',':','s','e','a','r','c','h','>',0
1499 };
1500
1501 static const WCHAR szComplete6[] = {
1502     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
1503     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
1504     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
1505 };
1506
1507 #define DECL_WIN_1252 \
1508 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
1509
1510 static const char win1252xml[] =
1511 DECL_WIN_1252
1512 "<open></open>";
1513
1514 static const char win1252decl[] =
1515 DECL_WIN_1252
1516 ;
1517
1518 static const char szExampleXML[] =
1519 "<?xml version='1.0' encoding='utf-8'?>\n"
1520 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
1521 "    <elem>\n"
1522 "        <a>A1 field</a>\n"
1523 "        <b>B1 field</b>\n"
1524 "        <c>C1 field</c>\n"
1525 "        <d>D1 field</d>\n"
1526 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1527 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
1528 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
1529 "            </html>\n"
1530 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
1531 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
1532 "            </html>\n"
1533 "        </description>\n"
1534 "    </elem>\n"
1535 "\n"
1536 "    <elem>\n"
1537 "        <a>A2 field</a>\n"
1538 "        <b>B2 field</b>\n"
1539 "        <c type=\"old\">C2 field</c>\n"
1540 "        <d>D2 field</d>\n"
1541 "    </elem>\n"
1542 "\n"
1543 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
1544 "        <a>A3 field</a>\n"
1545 "        <b>B3 field</b>\n"
1546 "        <c>C3 field</c>\n"
1547 "    </elem>\n"
1548 "\n"
1549 "    <elem>\n"
1550 "        <a>A4 field</a>\n"
1551 "        <b>B4 field</b>\n"
1552 "        <foo:c>C4 field</foo:c>\n"
1553 "        <d>D4 field</d>\n"
1554 "    </elem>\n"
1555 "</root>\n";
1556
1557 static const CHAR szNodeTypesXML[] =
1558 "<?xml version='1.0'?>"
1559 "<!-- comment node 0 -->"
1560 "<root id='0' depth='0'>"
1561 "   <!-- comment node 1 -->"
1562 "   text node 0"
1563 "   <x id='1' depth='1'>"
1564 "       <?foo value='PI for x'?>"
1565 "       <!-- comment node 2 -->"
1566 "       text node 1"
1567 "       <a id='3' depth='2'/>"
1568 "       <b id='4' depth='2'/>"
1569 "       <c id='5' depth='2'/>"
1570 "   </x>"
1571 "   <y id='2' depth='1'>"
1572 "       <?bar value='PI for y'?>"
1573 "       <!-- comment node 3 -->"
1574 "       text node 2"
1575 "       <a id='6' depth='2'/>"
1576 "       <b id='7' depth='2'/>"
1577 "       <c id='8' depth='2'/>"
1578 "   </y>"
1579 "</root>";
1580
1581 static const CHAR szTransformXML[] =
1582 "<?xml version=\"1.0\"?>\n"
1583 "<greeting>\n"
1584 "Hello World\n"
1585 "</greeting>";
1586
1587 static  const CHAR szTransformSSXML[] =
1588 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
1589 "   <xsl:output method=\"html\"/>\n"
1590 "   <xsl:template match=\"/\">\n"
1591 "       <xsl:apply-templates select=\"greeting\"/>\n"
1592 "   </xsl:template>\n"
1593 "   <xsl:template match=\"greeting\">\n"
1594 "       <html>\n"
1595 "           <body>\n"
1596 "               <h1>\n"
1597 "                   <xsl:value-of select=\".\"/>\n"
1598 "               </h1>\n"
1599 "           </body>\n"
1600 "       </html>\n"
1601 "   </xsl:template>\n"
1602 "</xsl:stylesheet>";
1603
1604 static  const CHAR szTransformOutput[] =
1605 "<html><body><h1>"
1606 "Hello World"
1607 "</h1></body></html>";
1608
1609 static const CHAR szTypeValueXML[] =
1610 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1611 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
1612 "   <string>Wine</string>\n"
1613 "   <string2 dt:dt=\"string\">String</string2>\n"
1614 "   <number dt:dt=\"number\">12.44</number>\n"
1615 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
1616 "   <int dt:dt=\"int\">-13</int>\n"
1617 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
1618 "   <bool dt:dt=\"boolean\">1</bool>\n"
1619 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
1620 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
1621 "   <date dt:dt=\"date\">3721-11-01</date>\n"
1622 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
1623 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
1624 "   <i1 dt:dt=\"i1\">-13</i1>\n"
1625 "   <i2 dt:dt=\"i2\">31915</i2>\n"
1626 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
1627 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
1628 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
1629 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
1630 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
1631 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
1632 "   <float dt:dt=\"float\">41221.421</float>\n"
1633 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
1634 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
1635 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
1636 "   <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
1637 "   <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z  ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
1638 "</root>";
1639
1640 static const CHAR szBasicTransformSSXMLPart1[] =
1641 "<?xml version=\"1.0\"?>"
1642 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
1643 "<xsl:output method=\"html\"/>\n"
1644 "<xsl:template match=\"/\">"
1645 "<HTML><BODY><TABLE>"
1646 "        <xsl:apply-templates select='document(\"";
1647
1648 static const CHAR szBasicTransformSSXMLPart2[] =
1649 "\")/bottle/wine'>"
1650 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
1651 "        </xsl:apply-templates>"
1652 "</TABLE></BODY></HTML>"
1653 "</xsl:template>"
1654 "<xsl:template match=\"bottle\">"
1655 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
1656 "</xsl:template>"
1657 "<xsl:template match=\"name\">"
1658 "   <TD><xsl:apply-templates /></TD>"
1659 "</xsl:template>"
1660 "<xsl:template match=\"cost\">"
1661 "   <TD><xsl:apply-templates /></TD>"
1662 "</xsl:template>"
1663 "</xsl:stylesheet>";
1664
1665 static const CHAR szBasicTransformXML[] =
1666 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
1667
1668 static const CHAR szBasicTransformOutput[] =
1669 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
1670
1671 #define SZ_EMAIL_DTD \
1672 "<!DOCTYPE email ["\
1673 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
1674 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
1675 "       <!ATTLIST email sent (yes|no) \"no\">"\
1676 "   <!ELEMENT recipients    (to+,cc*)>"\
1677 "   <!ELEMENT to            (#PCDATA)>"\
1678 "       <!ATTLIST to name CDATA #IMPLIED>"\
1679 "   <!ELEMENT cc            (#PCDATA)>"\
1680 "       <!ATTLIST cc name CDATA #IMPLIED>"\
1681 "   <!ELEMENT from          (#PCDATA)>"\
1682 "       <!ATTLIST from name CDATA #IMPLIED>"\
1683 "   <!ELEMENT reply-to      (#PCDATA)>"\
1684 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
1685 "   <!ELEMENT subject       ANY>"\
1686 "   <!ELEMENT body          ANY>"\
1687 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
1688 "   <!ELEMENT attachment    (#PCDATA)>"\
1689 "       <!ATTLIST attachment id ID #REQUIRED>"\
1690 "]>"
1691
1692 static const CHAR szEmailXML[] =
1693 "<?xml version=\"1.0\"?>"
1694 SZ_EMAIL_DTD
1695 "<email attachments=\"patch1\">"
1696 "   <recipients>"
1697 "       <to>wine-patches@winehq.org</to>"
1698 "   </recipients>"
1699 "   <from name=\"Anonymous\">user@localhost</from>"
1700 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
1701 "   <body>"
1702 "       It no longer causes spontaneous combustion..."
1703 "   </body>"
1704 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1705 "</email>";
1706
1707 static const CHAR szEmailXML_0D[] =
1708 "<?xml version=\"1.0\"?>"
1709 SZ_EMAIL_DTD
1710 "<email attachments=\"patch1\">"
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 88)</subject>"
1716 "   <body>"
1717 "       <undecl />"
1718 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
1719 "   </body>"
1720 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1721 "</email>";
1722
1723 static const CHAR szEmailXML_0E[] =
1724 "<?xml version=\"1.0\"?>"
1725 SZ_EMAIL_DTD
1726 "<email attachments=\"patch1\">"
1727 "   <recipients>"
1728 "       <to>wine-patches@winehq.org</to>"
1729 "   </recipients>"
1730 "   <from name=\"Anonymous\">user@localhost</from>"
1731 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
1732 "   <body>"
1733 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1734 "   </body>"
1735 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1736 "</email>";
1737
1738 static const CHAR szEmailXML_11[] =
1739 "<?xml version=\"1.0\"?>"
1740 SZ_EMAIL_DTD
1741 "<email attachments=\"patch1\">"
1742 "   <recipients>"
1743 "   </recipients>"
1744 "   <from name=\"Anonymous\">user@localhost</from>"
1745 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
1746 "   <body>"
1747 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1748 "   </body>"
1749 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1750 "</email>";
1751
1752 static const CHAR szEmailXML_13[] =
1753 "<?xml version=\"1.0\"?>"
1754 SZ_EMAIL_DTD
1755 "<msg attachments=\"patch1\">"
1756 "   <recipients>"
1757 "       <to>wine-patches@winehq.org</to>"
1758 "   </recipients>"
1759 "   <from name=\"Anonymous\">user@localhost</from>"
1760 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
1761 "   <body>"
1762 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
1763 "   </body>"
1764 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1765 "</msg>";
1766
1767 static const CHAR szEmailXML_14[] =
1768 "<?xml version=\"1.0\"?>"
1769 SZ_EMAIL_DTD
1770 "<email attachments=\"patch1\">"
1771 "   <to>wine-patches@winehq.org</to>"
1772 "   <from name=\"Anonymous\">user@localhost</from>"
1773 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
1774 "   <body>"
1775 "       XML_INVALID_CONTENT 0xC00CE014"
1776 "   </body>"
1777 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1778 "</email>";
1779
1780 static const CHAR szEmailXML_15[] =
1781 "<?xml version=\"1.0\"?>"
1782 SZ_EMAIL_DTD
1783 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1784 "   <recipients>"
1785 "       <to>wine-patches@winehq.org</to>"
1786 "   </recipients>"
1787 "   <from name=\"Anonymous\">user@localhost</from>"
1788 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
1789 "   <body>"
1790 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1791 "   </body>"
1792 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1793 "</email>";
1794
1795 static const CHAR szEmailXML_16[] =
1796 "<?xml version=\"1.0\"?>"
1797 SZ_EMAIL_DTD
1798 "<email attachments=\"patch1\">"
1799 "   <recipients>"
1800 "       <to>wine-patches@winehq.org</to>"
1801 "   </recipients>"
1802 "   <from name=\"Anonymous\">user@localhost</from>"
1803 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
1804 "   <body enc=\"ASCII\">"
1805 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
1806 "   </body>"
1807 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1808 "</email>";
1809
1810 static const CHAR szEmailXML_17[] =
1811 "<?xml version=\"1.0\"?>"
1812 SZ_EMAIL_DTD
1813 "<email attachments=\"patch1\" sent=\"true\">"
1814 "   <recipients>"
1815 "       <to>wine-patches@winehq.org</to>"
1816 "   </recipients>"
1817 "   <from name=\"Anonymous\">user@localhost</from>"
1818 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
1819 "   <body>"
1820 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
1821 "   </body>"
1822 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1823 "</email>";
1824
1825 static const CHAR szEmailXML_18[] =
1826 "<?xml version=\"1.0\"?>"
1827 SZ_EMAIL_DTD
1828 "<email attachments=\"patch1\">"
1829 "   oops"
1830 "   <recipients>"
1831 "       <to>wine-patches@winehq.org</to>"
1832 "   </recipients>"
1833 "   <from name=\"Anonymous\">user@localhost</from>"
1834 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
1835 "   <body>"
1836 "       XML_ILLEGAL_TEXT 0xC00CE018"
1837 "   </body>"
1838 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1839 "</email>";
1840
1841 static const CHAR szEmailXML_20[] =
1842 "<?xml version=\"1.0\"?>"
1843 SZ_EMAIL_DTD
1844 "<email>"
1845 "   <recipients>"
1846 "       <to>wine-patches@winehq.org</to>"
1847 "   </recipients>"
1848 "   <from name=\"Anonymous\">user@localhost</from>"
1849 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
1850 "   <body>"
1851 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1852 "   </body>"
1853 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1854 "</email>";
1855
1856 static const char xpath_simple_list[] =
1857 "<?xml version=\"1.0\"?>"
1858 "<root>"
1859 "   <a attr1=\"1\" attr2=\"2\" />"
1860 "   <b/>"
1861 "   <c/>"
1862 "   <d/>"
1863 "</root>";
1864
1865 static const char default_ns_doc[] = {
1866     "<?xml version=\"1.0\"?>"
1867     "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1868     "    d=\"d attr\" />"
1869 };
1870
1871 static const char attributes_map[] = {
1872     "<?xml version=\"1.0\"?>"
1873     "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1874 };
1875
1876 static const WCHAR nonexistent_fileW[] = {
1877     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1878 };
1879 static const WCHAR nonexistent_attrW[] = {
1880     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1881 };
1882 static const WCHAR szDocument[] = {
1883     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1884 };
1885
1886 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1887 static WCHAR szdl[] = { 'd','l',0 };
1888 static const WCHAR szvr[] = { 'v','r',0 };
1889 static const WCHAR szlc[] = { 'l','c',0 };
1890 static WCHAR szbs[] = { 'b','s',0 };
1891 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1892 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1893 static const WCHAR szstar[] = { '*',0 };
1894 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1895
1896 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1897 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1898 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1899
1900 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1901 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
1902 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1903 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1904                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1905 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1906                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1907
1908 static WCHAR szAttribute[] = {'A','t','t','r',0 };
1909 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1910
1911 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1912                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1913 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1914                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1915                              '!',']',']','>',0};
1916 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1917 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1918
1919 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1920 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1921 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1922
1923 #define expect_bstr_eq_and_free(bstr, expect) { \
1924     BSTR bstrExp = alloc_str_from_narrow(expect); \
1925     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1926     SysFreeString(bstr); \
1927     SysFreeString(bstrExp); \
1928 }
1929
1930 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1931
1932 #define ole_check(expr) { \
1933     HRESULT r = expr; \
1934     ok(r == S_OK, #expr " returned %x\n", r); \
1935 }
1936
1937 #define ole_expect(expr, expect) { \
1938     HRESULT r = expr; \
1939     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1940 }
1941
1942 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1943
1944 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1945 {
1946     void *obj = NULL;
1947     HRESULT hr;
1948
1949     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1950     if (hr != S_OK)
1951         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
1952
1953     return obj;
1954 }
1955
1956 #define _create(cls) cls, #cls
1957
1958 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1959 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1960 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1961 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
1962 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1963
1964 static BSTR alloc_str_from_narrow(const char *str)
1965 {
1966     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1967     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
1968     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1969     return ret;
1970 }
1971
1972 static BSTR alloced_bstrs[256];
1973 static int alloced_bstrs_count;
1974
1975 static BSTR _bstr_(const char *str)
1976 {
1977     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1978     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1979     return alloced_bstrs[alloced_bstrs_count++];
1980 }
1981
1982 static void free_bstrs(void)
1983 {
1984     int i;
1985     for (i = 0; i < alloced_bstrs_count; i++)
1986         SysFreeString(alloced_bstrs[i]);
1987     alloced_bstrs_count = 0;
1988 }
1989
1990 static VARIANT _variantbstr_(const char *str)
1991 {
1992     VARIANT v;
1993     V_VT(&v) = VT_BSTR;
1994     V_BSTR(&v) = _bstr_(str);
1995     return v;
1996 }
1997
1998 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1999 {
2000     for (;;)
2001     {
2002         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
2003         while (*sRight == '\r' || *sRight == '\n') sRight++;
2004         if (*sLeft != *sRight) return FALSE;
2005         if (!*sLeft) return TRUE;
2006         sLeft++;
2007         sRight++;
2008     }
2009 }
2010
2011 static void get_str_for_type(DOMNodeType type, char *buf)
2012 {
2013     switch (type)
2014     {
2015         case NODE_ATTRIBUTE:
2016             strcpy(buf, "A");
2017             break;
2018         case NODE_ELEMENT:
2019             strcpy(buf, "E");
2020             break;
2021         case NODE_DOCUMENT:
2022             strcpy(buf, "D");
2023             break;
2024         case NODE_TEXT:
2025             strcpy(buf, "T");
2026             break;
2027         case NODE_COMMENT:
2028             strcpy(buf, "C");
2029             break;
2030         case NODE_PROCESSING_INSTRUCTION:
2031             strcpy(buf, "P");
2032             break;
2033         default:
2034             wsprintfA(buf, "[%d]", type);
2035     }
2036 }
2037
2038 static int get_node_position(IXMLDOMNode *node)
2039 {
2040     HRESULT r;
2041     int pos = 0;
2042
2043     IXMLDOMNode_AddRef(node);
2044     do
2045     {
2046         IXMLDOMNode *new_node;
2047
2048         pos++;
2049         r = IXMLDOMNode_get_previousSibling(node, &new_node);
2050         ok(SUCCEEDED(r), "get_previousSibling failed\n");
2051         IXMLDOMNode_Release(node);
2052         node = new_node;
2053     } while (r == S_OK);
2054     return pos;
2055 }
2056
2057 static void node_to_string(IXMLDOMNode *node, char *buf)
2058 {
2059     HRESULT r = S_OK;
2060     DOMNodeType type;
2061
2062     if (node == NULL)
2063     {
2064         lstrcpyA(buf, "(null)");
2065         return;
2066     }
2067
2068     IXMLDOMNode_AddRef(node);
2069     while (r == S_OK)
2070     {
2071         IXMLDOMNode *new_node;
2072
2073         ole_check(IXMLDOMNode_get_nodeType(node, &type));
2074         get_str_for_type(type, buf);
2075         buf+=strlen(buf);
2076
2077         if (type == NODE_ATTRIBUTE)
2078         {
2079             BSTR bstr;
2080             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
2081             *(buf++) = '\'';
2082             wsprintfA(buf, "%ws", bstr);
2083             buf += strlen(buf);
2084             *(buf++) = '\'';
2085             SysFreeString(bstr);
2086
2087             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
2088         }
2089         else
2090         {
2091             r = IXMLDOMNode_get_parentNode(node, &new_node);
2092             wsprintf(buf, "%d", get_node_position(node));
2093             buf += strlen(buf);
2094         }
2095
2096         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
2097         IXMLDOMNode_Release(node);
2098         node = new_node;
2099         if (r == S_OK)
2100             *(buf++) = '.';
2101     }
2102
2103     *buf = 0;
2104 }
2105
2106 static char *list_to_string(IXMLDOMNodeList *list)
2107 {
2108     static char buf[4096];
2109     char *pos = buf;
2110     LONG len = 0;
2111     int i;
2112
2113     if (list == NULL)
2114     {
2115         lstrcpyA(buf, "(null)");
2116         return buf;
2117     }
2118     ole_check(IXMLDOMNodeList_get_length(list, &len));
2119     for (i = 0; i < len; i++)
2120     {
2121         IXMLDOMNode *node;
2122         if (i > 0)
2123             *(pos++) = ' ';
2124         ole_check(IXMLDOMNodeList_nextNode(list, &node));
2125         node_to_string(node, pos);
2126         pos += strlen(pos);
2127         IXMLDOMNode_Release(node);
2128     }
2129     *pos = 0;
2130     return buf;
2131 }
2132
2133 #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); }
2134 #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); }
2135
2136 struct docload_ret_t {
2137     VARIANT_BOOL b;
2138     HRESULT hr;
2139 };
2140
2141 struct leading_spaces_t {
2142     const CLSID *clsid;
2143     const char *name;
2144     struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
2145 };
2146
2147 static const struct leading_spaces_t leading_spaces_classdata[] = {
2148     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2149     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2150     { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE,  S_OK } }},
2151     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2152     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2153     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
2154     { NULL }
2155 };
2156
2157 static const char* leading_spaces_xmldata[] = {
2158     "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
2159     " <?xml version=\"1.0\"?><root/>",
2160     "\n<?xml version=\"1.0\"?><root/>",
2161     "\t<?xml version=\"1.0\"?><root/>",
2162     "\r\n<?xml version=\"1.0\"?><root/>",
2163     "\r<?xml version=\"1.0\"?><root/>",
2164     "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
2165     0
2166 };
2167
2168 static void test_domdoc( void )
2169 {
2170     HRESULT r, hr;
2171     IXMLDOMDocument *doc;
2172     IXMLDOMParseError *error;
2173     IXMLDOMElement *element = NULL;
2174     IXMLDOMNode *node;
2175     IXMLDOMText *nodetext = NULL;
2176     IXMLDOMComment *node_comment = NULL;
2177     IXMLDOMAttribute *node_attr = NULL;
2178     IXMLDOMNode *nodeChild = NULL;
2179     IXMLDOMProcessingInstruction *nodePI = NULL;
2180     const struct leading_spaces_t *class_ptr;
2181     const char **data_ptr;
2182     VARIANT_BOOL b;
2183     VARIANT var;
2184     BSTR str;
2185     LONG code, ref;
2186     LONG nLength = 0;
2187     WCHAR buff[100];
2188     char path[MAX_PATH];
2189     int index;
2190
2191     GetTempPathA(MAX_PATH, path);
2192     strcat(path, "leading_spaces.xml");
2193
2194     /* Load document with leading spaces
2195      *
2196      * Test all CLSIDs with all test data XML strings
2197      */
2198     class_ptr = leading_spaces_classdata;
2199     index = 0;
2200     while (class_ptr->clsid)
2201     {
2202         HRESULT hr;
2203         int i;
2204
2205         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
2206              &IID_IXMLDOMDocument, (void**)&doc);
2207         if (hr != S_OK) {
2208             win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
2209             class_ptr++;
2210             index++;
2211             continue;
2212         }
2213
2214         data_ptr = leading_spaces_xmldata;
2215         i = 0;
2216         while (*data_ptr) {
2217             BSTR data = _bstr_(*data_ptr);
2218             DWORD written;
2219             HANDLE file;
2220
2221             file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2222             ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
2223
2224             WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
2225             CloseHandle(file);
2226
2227             b = 0xc;
2228             V_VT(&var) = VT_BSTR;
2229             V_BSTR(&var) = _bstr_(path);
2230             hr = IXMLDOMDocument_load(doc, var, &b);
2231         todo_wine {
2232             EXPECT_HR(hr, class_ptr->ret[0].hr);
2233             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
2234         }
2235             DeleteFileA(path);
2236
2237             b = 0xc;
2238             hr = IXMLDOMDocument_loadXML(doc, data, &b);
2239             EXPECT_HR(hr, class_ptr->ret[1].hr);
2240             ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
2241
2242             data_ptr++;
2243             i++;
2244         }
2245
2246         class_ptr++;
2247         index++;
2248         free_bstrs();
2249     }
2250
2251     doc = create_document(&IID_IXMLDOMDocument);
2252     if (!doc) return;
2253
2254 if (0)
2255 {
2256     /* crashes on native */
2257     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
2258 }
2259
2260     /* try some stupid things */
2261     hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2262     EXPECT_HR(hr, S_FALSE);
2263
2264     b = VARIANT_TRUE;
2265     hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
2266     EXPECT_HR(hr, S_FALSE);
2267     ok( b == VARIANT_FALSE, "failed to load XML string\n");
2268
2269     /* try to load a document from a nonexistent file */
2270     b = VARIANT_TRUE;
2271     str = SysAllocString( nonexistent_fileW );
2272     VariantInit(&var);
2273     V_VT(&var) = VT_BSTR;
2274     V_BSTR(&var) = str;
2275
2276     r = IXMLDOMDocument_load( doc, var, &b);
2277     ok( r == S_FALSE, "loadXML succeeded\n");
2278     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2279     SysFreeString( str );
2280
2281     /* try load an empty document */
2282     b = VARIANT_TRUE;
2283     str = SysAllocString( szEmpty );
2284     r = IXMLDOMDocument_loadXML( doc, str, &b );
2285     ok( r == S_FALSE, "loadXML succeeded\n");
2286     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2287     SysFreeString( str );
2288
2289     r = IXMLDOMDocument_get_async( doc, &b );
2290     ok( r == S_OK, "get_async failed (%08x)\n", r);
2291     ok( b == VARIANT_TRUE, "Wrong default value\n");
2292
2293     /* check that there's no document element */
2294     element = NULL;
2295     r = IXMLDOMDocument_get_documentElement( doc, &element );
2296     ok( r == S_FALSE, "should be no document element\n");
2297
2298     /* try finding a node */
2299     node = NULL;
2300     str = SysAllocString( szstr1 );
2301     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
2302     ok( r == S_FALSE, "ret %08x\n", r );
2303     SysFreeString( str );
2304
2305     b = VARIANT_TRUE;
2306     str = SysAllocString( szIncomplete );
2307     r = IXMLDOMDocument_loadXML( doc, str, &b );
2308     ok( r == S_FALSE, "loadXML succeeded\n");
2309     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2310     SysFreeString( str );
2311
2312     /* check that there's no document element */
2313     element = (IXMLDOMElement*)1;
2314     r = IXMLDOMDocument_get_documentElement( doc, &element );
2315     ok( r == S_FALSE, "should be no document element\n");
2316     ok( element == NULL, "Element should be NULL\n");
2317
2318     /* test for BSTR handling, pass broken BSTR */
2319     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
2320     /* just a big length */
2321     *(DWORD*)buff = 0xf0f0;
2322     b = VARIANT_FALSE;
2323     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
2324     ok( r == S_OK, "loadXML failed\n");
2325     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2326
2327     /* loadXML ignores the encoding attribute and always expects Unicode */
2328     b = VARIANT_FALSE;
2329     str = SysAllocString( szComplete6 );
2330     r = IXMLDOMDocument_loadXML( doc, str, &b );
2331     ok( r == S_OK, "loadXML failed\n");
2332     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2333     SysFreeString( str );
2334
2335     /* try a BSTR containing a Windows-1252 document */
2336     b = VARIANT_TRUE;
2337     str = SysAllocStringByteLen( win1252xml, strlen(win1252xml) );
2338     r = IXMLDOMDocument_loadXML( doc, str, &b );
2339     ok( r == S_FALSE, "loadXML succeeded\n");
2340     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
2341     SysFreeString( str );
2342
2343     /* try to load something valid */
2344     b = VARIANT_FALSE;
2345     str = SysAllocString( szComplete1 );
2346     r = IXMLDOMDocument_loadXML( doc, str, &b );
2347     ok( r == S_OK, "loadXML failed\n");
2348     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2349     SysFreeString( str );
2350
2351     /* check if nodename is correct */
2352     r = IXMLDOMDocument_get_nodeName( doc, NULL );
2353     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2354
2355     str = (BSTR)0xdeadbeef;
2356     r = IXMLDOMDocument_get_baseName( doc, &str );
2357     ok ( r == S_FALSE, "got 0x%08x\n", r);
2358     ok (str == NULL, "got %p\n", str);
2359
2360     /* content doesn't matter here */
2361     str = NULL;
2362     r = IXMLDOMDocument_get_nodeName( doc, &str );
2363     ok ( r == S_OK, "get_nodeName wrong code\n");
2364     ok ( str != NULL, "str is null\n");
2365     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
2366     SysFreeString( str );
2367
2368     /* test put_text */
2369     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
2370     ok( r == E_FAIL, "ret %08x\n", r );
2371
2372     /* check that there's a document element */
2373     element = NULL;
2374     r = IXMLDOMDocument_get_documentElement( doc, &element );
2375     ok( r == S_OK, "should be a document element\n");
2376     if( element )
2377     {
2378         IObjectIdentity *ident;
2379
2380         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
2381         ok( r == E_NOINTERFACE, "ret %08x\n", r);
2382
2383         IXMLDOMElement_Release( element );
2384         element = NULL;
2385     }
2386
2387     /* as soon as we call loadXML again, the document element will disappear */
2388     b = 2;
2389     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
2390     ok( r == S_FALSE, "loadXML failed\n");
2391     ok( b == 2, "variant modified\n");
2392     r = IXMLDOMDocument_get_documentElement( doc, &element );
2393     ok( r == S_FALSE, "should be no document element\n");
2394
2395     /* try to load something else simple and valid */
2396     b = VARIANT_FALSE;
2397     str = SysAllocString( szComplete3 );
2398     r = IXMLDOMDocument_loadXML( doc, str, &b );
2399     ok( r == S_OK, "loadXML failed\n");
2400     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2401     SysFreeString( str );
2402
2403     /* try something a little more complicated */
2404     b = FALSE;
2405     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2406     ok( r == S_OK, "loadXML failed\n");
2407     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2408
2409     r = IXMLDOMDocument_get_parseError( doc, &error );
2410     ok( r == S_OK, "returns %08x\n", r );
2411
2412     r = IXMLDOMParseError_get_errorCode( error, &code );
2413     ok( r == S_FALSE, "returns %08x\n", r );
2414     ok( code == 0, "code %d\n", code );
2415     IXMLDOMParseError_Release( error );
2416
2417     /* test createTextNode */
2418     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
2419     ok( r == S_OK, "returns %08x\n", r );
2420     IXMLDOMText_Release(nodetext);
2421
2422     str = SysAllocString( szOpen );
2423     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
2424     ok( r == E_INVALIDARG, "returns %08x\n", r );
2425     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
2426     ok( r == S_OK, "returns %08x\n", r );
2427     SysFreeString( str );
2428     if(nodetext)
2429     {
2430         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
2431         ok(r == E_NOINTERFACE, "ret %08x\n", r );
2432
2433         /* Text Last Child Checks */
2434         r = IXMLDOMText_get_lastChild(nodetext, NULL);
2435         ok(r == E_INVALIDARG, "ret %08x\n", r );
2436
2437         nodeChild = (IXMLDOMNode*)0x1;
2438         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
2439         ok(r == S_FALSE, "ret %08x\n", r );
2440         ok(nodeChild == NULL, "nodeChild not NULL\n");
2441
2442         /* test length property */
2443         r = IXMLDOMText_get_length(nodetext, NULL);
2444         ok(r == E_INVALIDARG, "ret %08x\n", r );
2445
2446         r = IXMLDOMText_get_length(nodetext, &nLength);
2447         ok(r == S_OK, "ret %08x\n", r );
2448         ok(nLength == 4, "expected 4 got %d\n", nLength);
2449
2450         /* put data Tests */
2451         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
2452         ok(r == S_OK, "ret %08x\n", r );
2453
2454         /* get data Tests */
2455         r = IXMLDOMText_get_data(nodetext, &str);
2456         ok(r == S_OK, "ret %08x\n", r );
2457         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
2458         SysFreeString(str);
2459
2460         /* Confirm XML text is good */
2461         r = IXMLDOMText_get_xml(nodetext, &str);
2462         ok(r == S_OK, "ret %08x\n", r );
2463         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
2464         SysFreeString(str);
2465
2466         /* Confirm we get the put_data Text back */
2467         r = IXMLDOMText_get_text(nodetext, &str);
2468         ok(r == S_OK, "ret %08x\n", r );
2469         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2470         SysFreeString(str);
2471
2472         /* test substringData */
2473         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
2474         ok(r == E_INVALIDARG, "ret %08x\n", r );
2475
2476         /* test substringData - Invalid offset */
2477         str = (BSTR)&szElement;
2478         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
2479         ok(r == E_INVALIDARG, "ret %08x\n", r );
2480         ok( str == NULL, "incorrect string\n");
2481
2482         /* test substringData - Invalid offset */
2483         str = (BSTR)&szElement;
2484         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
2485         ok(r == S_FALSE, "ret %08x\n", r );
2486         ok( str == NULL, "incorrect string\n");
2487
2488         /* test substringData - Invalid size */
2489         str = (BSTR)&szElement;
2490         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
2491         ok(r == E_INVALIDARG, "ret %08x\n", r );
2492         ok( str == NULL, "incorrect string\n");
2493
2494         /* test substringData - Invalid size */
2495         str = (BSTR)&szElement;
2496         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
2497         ok(r == S_FALSE, "ret %08x\n", r );
2498         ok( str == NULL, "incorrect string\n");
2499
2500         /* test substringData - Start of string */
2501         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
2502         ok(r == S_OK, "ret %08x\n", r );
2503         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2504         SysFreeString(str);
2505
2506         /* test substringData - Middle of string */
2507         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
2508         ok(r == S_OK, "ret %08x\n", r );
2509         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2510         SysFreeString(str);
2511
2512         /* test substringData - End of string */
2513         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
2514         ok(r == S_OK, "ret %08x\n", r );
2515         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2516         SysFreeString(str);
2517
2518         /* test appendData */
2519         r = IXMLDOMText_appendData(nodetext, NULL);
2520         ok(r == S_OK, "ret %08x\n", r );
2521
2522         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
2523         ok(r == S_OK, "ret %08x\n", r );
2524
2525         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
2526         ok(r == S_OK, "ret %08x\n", r );
2527
2528         r = IXMLDOMText_get_text(nodetext, &str);
2529         ok(r == S_OK, "ret %08x\n", r );
2530         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2531         SysFreeString(str);
2532
2533         /* test insertData */
2534         str = SysAllocStringLen(NULL, 0);
2535         r = IXMLDOMText_insertData(nodetext, -1, str);
2536         ok(r == S_OK, "ret %08x\n", r );
2537
2538         r = IXMLDOMText_insertData(nodetext, -1, NULL);
2539         ok(r == S_OK, "ret %08x\n", r );
2540
2541         r = IXMLDOMText_insertData(nodetext, 1000, str);
2542         ok(r == S_OK, "ret %08x\n", r );
2543
2544         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
2545         ok(r == S_OK, "ret %08x\n", r );
2546
2547         r = IXMLDOMText_insertData(nodetext, 0, NULL);
2548         ok(r == S_OK, "ret %08x\n", r );
2549
2550         r = IXMLDOMText_insertData(nodetext, 0, str);
2551         ok(r == S_OK, "ret %08x\n", r );
2552         SysFreeString(str);
2553
2554         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
2555         ok(r == E_INVALIDARG, "ret %08x\n", r );
2556
2557         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
2558         ok(r == E_INVALIDARG, "ret %08x\n", r );
2559
2560         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
2561         ok(r == S_OK, "ret %08x\n", r );
2562
2563         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
2564         ok(r == S_OK, "ret %08x\n", r );
2565
2566         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
2567         ok(r == S_OK, "ret %08x\n", r );
2568
2569         r = IXMLDOMText_get_text(nodetext, &str);
2570         ok(r == S_OK, "ret %08x\n", r );
2571         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2572         SysFreeString(str);
2573
2574         /* delete data */
2575         /* invalid arguments */
2576         r = IXMLDOMText_deleteData(nodetext, -1, 1);
2577         ok(r == E_INVALIDARG, "ret %08x\n", r );
2578
2579         r = IXMLDOMText_deleteData(nodetext, 0, 0);
2580         ok(r == S_OK, "ret %08x\n", r );
2581
2582         r = IXMLDOMText_deleteData(nodetext, 0, -1);
2583         ok(r == E_INVALIDARG, "ret %08x\n", r );
2584
2585         r = IXMLDOMText_get_length(nodetext, &nLength);
2586         ok(r == S_OK, "ret %08x\n", r );
2587         ok(nLength == 43, "expected 43 got %d\n", nLength);
2588
2589         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
2590         ok(r == S_OK, "ret %08x\n", r );
2591
2592         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
2593         ok(r == E_INVALIDARG, "ret %08x\n", r );
2594
2595         /* delete from start */
2596         r = IXMLDOMText_deleteData(nodetext, 0, 5);
2597         ok(r == S_OK, "ret %08x\n", r );
2598
2599         r = IXMLDOMText_get_length(nodetext, &nLength);
2600         ok(r == S_OK, "ret %08x\n", r );
2601         ok(nLength == 38, "expected 38 got %d\n", nLength);
2602
2603         r = IXMLDOMText_get_text(nodetext, &str);
2604         ok(r == S_OK, "ret %08x\n", r );
2605         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2606         SysFreeString(str);
2607
2608         /* delete from end */
2609         r = IXMLDOMText_deleteData(nodetext, 35, 3);
2610         ok(r == S_OK, "ret %08x\n", r );
2611
2612         r = IXMLDOMText_get_length(nodetext, &nLength);
2613         ok(r == S_OK, "ret %08x\n", r );
2614         ok(nLength == 35, "expected 35 got %d\n", nLength);
2615
2616         r = IXMLDOMText_get_text(nodetext, &str);
2617         ok(r == S_OK, "ret %08x\n", r );
2618         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2619         SysFreeString(str);
2620
2621         /* delete from inside */
2622         r = IXMLDOMText_deleteData(nodetext, 1, 33);
2623         ok(r == S_OK, "ret %08x\n", r );
2624
2625         r = IXMLDOMText_get_length(nodetext, &nLength);
2626         ok(r == S_OK, "ret %08x\n", r );
2627         ok(nLength == 2, "expected 2 got %d\n", nLength);
2628
2629         r = IXMLDOMText_get_text(nodetext, &str);
2630         ok(r == S_OK, "ret %08x\n", r );
2631         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2632         SysFreeString(str);
2633
2634         /* delete whole data ... */
2635         r = IXMLDOMText_get_length(nodetext, &nLength);
2636         ok(r == S_OK, "ret %08x\n", r );
2637
2638         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2639         ok(r == S_OK, "ret %08x\n", r );
2640         /* ... and try again with empty string */
2641         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
2642         ok(r == S_OK, "ret %08x\n", r );
2643
2644         /* test put_data */
2645         V_VT(&var) = VT_BSTR;
2646         V_BSTR(&var) = SysAllocString(szstr1);
2647         r = IXMLDOMText_put_nodeValue(nodetext, var);
2648         ok(r == S_OK, "ret %08x\n", r );
2649         VariantClear(&var);
2650
2651         r = IXMLDOMText_get_text(nodetext, &str);
2652         ok(r == S_OK, "ret %08x\n", r );
2653         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2654         SysFreeString(str);
2655
2656         /* test put_data */
2657         V_VT(&var) = VT_I4;
2658         V_I4(&var) = 99;
2659         r = IXMLDOMText_put_nodeValue(nodetext, var);
2660         ok(r == S_OK, "ret %08x\n", r );
2661         VariantClear(&var);
2662
2663         r = IXMLDOMText_get_text(nodetext, &str);
2664         ok(r == S_OK, "ret %08x\n", r );
2665         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2666         SysFreeString(str);
2667
2668         /* ::replaceData() */
2669         V_VT(&var) = VT_BSTR;
2670         V_BSTR(&var) = SysAllocString(szstr1);
2671         r = IXMLDOMText_put_nodeValue(nodetext, var);
2672         ok(r == S_OK, "ret %08x\n", r );
2673         VariantClear(&var);
2674
2675         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
2676         ok(r == E_INVALIDARG, "ret %08x\n", r );
2677         r = IXMLDOMText_get_text(nodetext, &str);
2678         ok(r == S_OK, "ret %08x\n", r );
2679         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2680         SysFreeString(str);
2681
2682         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
2683         ok(r == S_OK, "ret %08x\n", r );
2684         r = IXMLDOMText_get_text(nodetext, &str);
2685         ok(r == S_OK, "ret %08x\n", r );
2686         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2687         SysFreeString(str);
2688
2689         /* NULL pointer means delete */
2690         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
2691         ok(r == S_OK, "ret %08x\n", r );
2692         r = IXMLDOMText_get_text(nodetext, &str);
2693         ok(r == S_OK, "ret %08x\n", r );
2694         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2695         SysFreeString(str);
2696
2697         /* empty string means delete */
2698         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
2699         ok(r == S_OK, "ret %08x\n", r );
2700         r = IXMLDOMText_get_text(nodetext, &str);
2701         ok(r == S_OK, "ret %08x\n", r );
2702         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2703         SysFreeString(str);
2704
2705         /* zero count means insert */
2706         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
2707         ok(r == S_OK, "ret %08x\n", r );
2708         r = IXMLDOMText_get_text(nodetext, &str);
2709         ok(r == S_OK, "ret %08x\n", r );
2710         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2711         SysFreeString(str);
2712
2713         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
2714         ok(r == S_OK, "ret %08x\n", r );
2715
2716         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
2717         ok(r == S_OK, "ret %08x\n", r );
2718         r = IXMLDOMText_get_text(nodetext, &str);
2719         ok(r == S_OK, "ret %08x\n", r );
2720         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2721         SysFreeString(str);
2722
2723         /* nonempty string, count greater than its length */
2724         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2725         ok(r == S_OK, "ret %08x\n", r );
2726         r = IXMLDOMText_get_text(nodetext, &str);
2727         ok(r == S_OK, "ret %08x\n", r );
2728         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2729         SysFreeString(str);
2730
2731         /* nonempty string, count less than its length */
2732         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2733         ok(r == S_OK, "ret %08x\n", r );
2734         r = IXMLDOMText_get_text(nodetext, &str);
2735         ok(r == S_OK, "ret %08x\n", r );
2736         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2737         SysFreeString(str);
2738
2739         IXMLDOMText_Release( nodetext );
2740     }
2741
2742     /* test Create Comment */
2743     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2744     ok( r == E_INVALIDARG, "returns %08x\n", r );
2745     node_comment = (IXMLDOMComment*)0x1;
2746
2747     /* empty comment */
2748     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2749     ok( r == S_OK, "returns %08x\n", r );
2750     str = (BSTR)0x1;
2751     r = IXMLDOMComment_get_data(node_comment, &str);
2752     ok( r == S_OK, "returns %08x\n", r );
2753     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2754     IXMLDOMComment_Release(node_comment);
2755     SysFreeString(str);
2756
2757     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2758     ok( r == S_OK, "returns %08x\n", r );
2759     str = (BSTR)0x1;
2760     r = IXMLDOMComment_get_data(node_comment, &str);
2761     ok( r == S_OK, "returns %08x\n", r );
2762     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2763     IXMLDOMComment_Release(node_comment);
2764     SysFreeString(str);
2765
2766     str = SysAllocString(szComment);
2767     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2768     SysFreeString(str);
2769     ok( r == S_OK, "returns %08x\n", r );
2770     if(node_comment)
2771     {
2772         /* Last Child Checks */
2773         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2774         ok(r == E_INVALIDARG, "ret %08x\n", r );
2775
2776         nodeChild = (IXMLDOMNode*)0x1;
2777         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2778         ok(r == S_FALSE, "ret %08x\n", r );
2779         ok(nodeChild == NULL, "pLastChild not NULL\n");
2780
2781         /* baseName */
2782         str = (BSTR)0xdeadbeef;
2783         r = IXMLDOMComment_get_baseName(node_comment, &str);
2784         ok(r == S_FALSE, "ret %08x\n", r );
2785         ok(str == NULL, "Expected NULL\n");
2786
2787         IXMLDOMComment_Release( node_comment );
2788     }
2789
2790     /* test Create Attribute */
2791     str = SysAllocString(szAttribute);
2792     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2793     ok( r == E_INVALIDARG, "returns %08x\n", r );
2794     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2795     ok( r == S_OK, "returns %08x\n", r );
2796     IXMLDOMAttribute_Release( node_attr);
2797     SysFreeString(str);
2798
2799     /* test Processing Instruction */
2800     str = SysAllocStringLen(NULL, 0);
2801     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2802     ok( r == E_INVALIDARG, "returns %08x\n", r );
2803     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2804     ok( r == E_FAIL, "returns %08x\n", r );
2805     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2806     ok( r == E_FAIL, "returns %08x\n", r );
2807     SysFreeString(str);
2808
2809     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2810     ok( r == S_OK, "returns %08x\n", r );
2811     if(nodePI)
2812     {
2813         /* Last Child Checks */
2814         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2815         ok(r == E_INVALIDARG, "ret %08x\n", r );
2816
2817         nodeChild = (IXMLDOMNode*)0x1;
2818         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2819         ok(r == S_FALSE, "ret %08x\n", r );
2820         ok(nodeChild == NULL, "nodeChild not NULL\n");
2821
2822         /* test nodeName */
2823         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2824         ok(r == S_OK, "ret %08x\n", r );
2825         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2826         SysFreeString(str);
2827
2828         /* test baseName */
2829         str = (BSTR)0x1;
2830         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2831         ok(r == S_OK, "ret %08x\n", r );
2832         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2833         SysFreeString(str);
2834
2835         /* test Target */
2836         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2837         ok(r == S_OK, "ret %08x\n", r );
2838         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2839         SysFreeString(str);
2840
2841         /* test get_data */
2842         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2843         ok(r == S_OK, "ret %08x\n", r );
2844         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2845         SysFreeString(str);
2846
2847         /* test put_data */
2848         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2849         ok(r == E_FAIL, "ret %08x\n", r );
2850
2851         /* test put_data */
2852         V_VT(&var) = VT_BSTR;
2853         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
2854         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2855         ok(r == E_FAIL, "ret %08x\n", r );
2856         VariantClear(&var);
2857
2858         /* test get nodeName */
2859         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2860         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2861         ok(r == S_OK, "ret %08x\n", r );
2862         SysFreeString(str);
2863
2864         IXMLDOMProcessingInstruction_Release(nodePI);
2865     }
2866
2867     ref = IXMLDOMDocument_Release( doc );
2868     ok( ref == 0, "got %d\n", ref);
2869
2870     free_bstrs();
2871 }
2872
2873 static void test_persiststreaminit(void)
2874 {
2875     IXMLDOMDocument *doc;
2876     IPersistStreamInit *streaminit;
2877     HRESULT hr;
2878
2879     doc = create_document(&IID_IXMLDOMDocument);
2880     if (!doc) return;
2881
2882     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2883     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2884
2885     hr = IPersistStreamInit_InitNew(streaminit);
2886     ok( hr == S_OK, "failed with 0x%08x\n", hr );
2887
2888     IXMLDOMDocument_Release(doc);
2889 }
2890
2891 static void test_domnode( void )
2892 {
2893     HRESULT r;
2894     IXMLDOMDocument *doc, *owner = NULL;
2895     IXMLDOMElement *element = NULL;
2896     IXMLDOMNamedNodeMap *map = NULL;
2897     IXMLDOMNode *node = NULL, *next = NULL;
2898     IXMLDOMNodeList *list = NULL;
2899     IXMLDOMAttribute *attr = NULL;
2900     DOMNodeType type = NODE_INVALID;
2901     VARIANT_BOOL b;
2902     BSTR str;
2903     VARIANT var;
2904     LONG count;
2905
2906     doc = create_document(&IID_IXMLDOMDocument);
2907     if (!doc) return;
2908
2909     b = FALSE;
2910     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2911     ok( r == S_OK, "loadXML failed\n");
2912     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2913
2914     EXPECT_CHILDREN(doc);
2915
2916     r = IXMLDOMDocument_get_documentElement( doc, &element );
2917     ok( r == S_OK, "should be a document element\n");
2918     ok( element != NULL, "should be an element\n");
2919
2920     VariantInit(&var);
2921     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2922
2923     r = IXMLDOMDocument_get_nodeValue( doc, NULL );
2924     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2925
2926     r = IXMLDOMDocument_get_nodeValue( doc, &var );
2927     ok( r == S_FALSE, "nextNode returned wrong code\n");
2928     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2929     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2930
2931     if (element)
2932     {
2933         owner = NULL;
2934         r = IXMLDOMElement_get_ownerDocument( element, &owner );
2935         ok( r == S_OK, "get_ownerDocument return code\n");
2936         ok( owner != doc, "get_ownerDocument return\n");
2937         IXMLDOMDocument_Release(owner);
2938
2939         type = NODE_INVALID;
2940         r = IXMLDOMElement_get_nodeType( element, &type);
2941         ok( r == S_OK, "got %08x\n", r);
2942         ok( type == NODE_ELEMENT, "node not an element\n");
2943
2944         str = NULL;
2945         r = IXMLDOMElement_get_baseName( element, &str );
2946         ok( r == S_OK, "get_baseName returned wrong code\n");
2947         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2948         SysFreeString(str);
2949
2950         /* check if nodename is correct */
2951         r = IXMLDOMElement_get_nodeName( element, NULL );
2952         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2953
2954         /* content doesn't matter here */
2955         str = NULL;
2956         r = IXMLDOMElement_get_nodeName( element, &str );
2957         ok ( r == S_OK, "get_nodeName wrong code\n");
2958         ok ( str != NULL, "str is null\n");
2959         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2960         SysFreeString( str );
2961
2962         str = SysAllocString( nonexistent_fileW );
2963         V_VT(&var) = VT_I4;
2964         V_I4(&var) = 0x1234;
2965         r = IXMLDOMElement_getAttribute( element, str, &var );
2966         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2967         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2968         VariantClear(&var);
2969
2970         str = SysAllocString( szdl );   
2971         V_VT(&var) = VT_I4;
2972         V_I4(&var) = 0x1234;
2973         r = IXMLDOMElement_getAttribute( element, str, &var );
2974         ok( r == S_OK, "getAttribute ret %08x\n", r );
2975         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2976         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2977         VariantClear( &var );
2978
2979         r = IXMLDOMElement_getAttribute( element, NULL, &var );
2980         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2981
2982         r = IXMLDOMElement_getAttribute( element, str, NULL );
2983         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2984
2985         attr = NULL;
2986         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2987         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2988         ok( attr != NULL, "getAttributeNode returned NULL\n" );
2989         if (attr)
2990         {
2991             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2992             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2993
2994             /* attribute doesn't have a parent in msxml interpretation */
2995             node = (IXMLDOMNode*)0xdeadbeef;
2996             r = IXMLDOMAttribute_get_parentNode( attr, &node );
2997             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2998             ok( node == NULL, "Expected NULL, got %p\n", node );
2999
3000             IXMLDOMAttribute_Release(attr);
3001         }
3002
3003         SysFreeString( str );
3004
3005         r = IXMLDOMElement_get_attributes( element, &map );
3006         ok( r == S_OK, "get_attributes returned wrong code\n");
3007         ok( map != NULL, "should be attributes\n");
3008
3009         EXPECT_CHILDREN(element);
3010     }
3011     else
3012         ok( FALSE, "no element\n");
3013
3014     if (map)
3015     {
3016         str = SysAllocString( szdl );
3017         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
3018         ok( r == S_OK, "getNamedItem returned wrong code\n");
3019         ok( node != NULL, "should be attributes\n");
3020         IXMLDOMNode_Release(node);
3021         SysFreeString( str );
3022
3023         str = SysAllocString( szdl );
3024         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
3025         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
3026         SysFreeString( str );
3027
3028         /* something that isn't in complete4A */
3029         str = SysAllocString( szOpen );
3030         node = (IXMLDOMNode *) 1;
3031         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
3032         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
3033         ok( node == NULL, "getNamedItem should have returned NULL\n");
3034         SysFreeString( str );
3035
3036         /* test indexed access of attributes */
3037         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
3038         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
3039
3040         r = IXMLDOMNamedNodeMap_get_length( map, &count );
3041         ok ( r == S_OK, "get_length wrong code\n");
3042         ok ( count == 1, "get_length != 1\n");
3043
3044         node = NULL;
3045         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
3046         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
3047         ok ( node == NULL, "there is no node\n");
3048
3049         node = NULL;
3050         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
3051         ok ( r == S_FALSE, "get_item (1) wrong code\n");
3052         ok ( node == NULL, "there is no attribute\n");
3053
3054         node = NULL;
3055         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
3056         ok ( r == S_OK, "get_item (0) wrong code\n");
3057         ok ( node != NULL, "should be attribute\n");
3058
3059         r = IXMLDOMNode_get_nodeName( node, NULL );
3060         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
3061
3062         /* content doesn't matter here */
3063         str = NULL;
3064         r = IXMLDOMNode_get_nodeName( node, &str );
3065         ok ( r == S_OK, "get_nodeName wrong code\n");
3066         ok ( str != NULL, "str is null\n");
3067         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
3068         SysFreeString( str );
3069         IXMLDOMNode_Release( node );
3070
3071         /* test sequential access of attributes */
3072         node = NULL;
3073         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
3074         ok ( r == S_OK, "nextNode (first time) wrong code\n");
3075         ok ( node != NULL, "nextNode, should be attribute\n");
3076         IXMLDOMNode_Release( node );
3077
3078         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
3079         ok ( r != S_OK, "nextNode (second time) wrong code\n");
3080         ok ( node == NULL, "nextNode, there is no attribute\n");
3081
3082         r = IXMLDOMNamedNodeMap_reset( map );
3083         ok ( r == S_OK, "reset should return S_OK\n");
3084
3085         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
3086         ok ( r == S_OK, "nextNode (third time) wrong code\n");
3087         ok ( node != NULL, "nextNode, should be attribute\n");
3088     }
3089     else
3090         ok( FALSE, "no map\n");
3091
3092     if (node)
3093     {
3094         type = NODE_INVALID;
3095         r = IXMLDOMNode_get_nodeType( node, &type);
3096         ok( r == S_OK, "getNamedItem returned wrong code\n");
3097         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
3098
3099         str = NULL;
3100         r = IXMLDOMNode_get_baseName( node, NULL );
3101         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
3102
3103         str = NULL;
3104         r = IXMLDOMNode_get_baseName( node, &str );
3105         ok( r == S_OK, "get_baseName returned wrong code\n");
3106         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
3107         SysFreeString( str );
3108
3109         r = IXMLDOMNode_get_childNodes( node, NULL );
3110         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
3111
3112         r = IXMLDOMNode_get_childNodes( node, &list );
3113         ok( r == S_OK, "get_childNodes returned wrong code\n");
3114
3115         if (list)
3116         {
3117             r = IXMLDOMNodeList_nextNode( list, &next );
3118             ok( r == S_OK, "nextNode returned wrong code\n");
3119         }
3120         else
3121             ok( FALSE, "no childlist\n");
3122
3123         if (next)
3124         {
3125             EXPECT_NO_CHILDREN(next);
3126
3127             type = NODE_INVALID;
3128             r = IXMLDOMNode_get_nodeType( next, &type);
3129             ok( r == S_OK, "getNamedItem returned wrong code\n");
3130             ok( type == NODE_TEXT, "node not text\n");
3131
3132             str = (BSTR) 1;
3133             r = IXMLDOMNode_get_baseName( next, &str );
3134             ok( r == S_FALSE, "get_baseName returned wrong code\n");
3135             ok( str == NULL, "basename was wrong\n");
3136             SysFreeString(str);
3137         }
3138         else
3139             ok( FALSE, "no next\n");
3140
3141         if (next)
3142             IXMLDOMNode_Release( next );
3143         next = NULL;
3144         if (list)
3145             IXMLDOMNodeList_Release( list );
3146         list = NULL;
3147         if (node)
3148             IXMLDOMNode_Release( node );
3149     }
3150     else
3151         ok( FALSE, "no node\n");
3152     node = NULL;
3153
3154     if (map)
3155         IXMLDOMNamedNodeMap_Release( map );
3156
3157     /* now traverse the tree from the root element */
3158     if (element)
3159     {
3160         r = IXMLDOMElement_get_childNodes( element, &list );
3161         ok( r == S_OK, "get_childNodes returned wrong code\n");
3162
3163         /* using get_item for child list doesn't advance the position */
3164         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
3165         expect_node(node, "E2.E2.D1");
3166         IXMLDOMNode_Release(node);
3167         ole_check(IXMLDOMNodeList_nextNode(list, &node));
3168         expect_node(node, "E1.E2.D1");
3169         IXMLDOMNode_Release(node);
3170         ole_check(IXMLDOMNodeList_reset(list));
3171
3172         IXMLDOMNodeList_AddRef(list);
3173         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
3174         ole_check(IXMLDOMNodeList_reset(list));
3175
3176         node = (void*)0xdeadbeef;
3177         str = SysAllocString(szdl);
3178         r = IXMLDOMElement_selectSingleNode( element, str, &node );
3179         SysFreeString(str);
3180         ok( r == S_FALSE, "ret %08x\n", r );
3181         ok( node == NULL, "node %p\n", node );
3182
3183         str = SysAllocString(szbs);
3184         r = IXMLDOMElement_selectSingleNode( element, str, &node );
3185         SysFreeString(str);
3186         ok( r == S_OK, "ret %08x\n", r );
3187         r = IXMLDOMNode_Release( node );
3188         ok( r == 0, "ret %08x\n", r );
3189     }
3190     else
3191         ok( FALSE, "no element\n");
3192
3193     if (list)
3194     {
3195         r = IXMLDOMNodeList_get_item(list, 0, NULL);
3196         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3197
3198         r = IXMLDOMNodeList_get_length(list, NULL);
3199         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3200
3201         r = IXMLDOMNodeList_get_length( list, &count );
3202         ok( r == S_OK, "get_length returns %08x\n", r );
3203         ok( count == 4, "get_length got %d\n", count );
3204
3205         r = IXMLDOMNodeList_nextNode(list, NULL);
3206         ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
3207
3208         r = IXMLDOMNodeList_nextNode( list, &node );
3209         ok( r == S_OK, "nextNode returned wrong code\n");
3210     }
3211     else
3212         ok( FALSE, "no list\n");
3213
3214     if (node)
3215     {
3216         type = NODE_INVALID;
3217         r = IXMLDOMNode_get_nodeType( node, &type);
3218         ok( r == S_OK, "getNamedItem returned wrong code\n");
3219         ok( type == NODE_ELEMENT, "node not text\n");
3220
3221         r = IXMLDOMNode_hasChildNodes( node, NULL );
3222         ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
3223
3224         EXPECT_CHILDREN(node);
3225
3226         str = NULL;
3227         r = IXMLDOMNode_get_baseName( node, &str );
3228         ok( r == S_OK, "get_baseName returned wrong code\n");
3229         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
3230         SysFreeString(str);
3231     }
3232     else
3233         ok( FALSE, "no node\n");
3234
3235     if (node)
3236         IXMLDOMNode_Release( node );
3237     if (list)
3238         IXMLDOMNodeList_Release( list );
3239     if (element)
3240         IXMLDOMElement_Release( element );
3241
3242     b = FALSE;
3243     str = SysAllocString( szComplete5 );
3244     r = IXMLDOMDocument_loadXML( doc, str, &b );
3245     ok( r == S_OK, "loadXML failed\n");
3246     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3247     SysFreeString( str );
3248
3249     EXPECT_CHILDREN(doc);
3250
3251     r = IXMLDOMDocument_get_documentElement( doc, &element );
3252     ok( r == S_OK, "should be a document element\n");
3253     ok( element != NULL, "should be an element\n");
3254
3255     if (element)
3256     {
3257         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
3258         BSTR tag = NULL;
3259
3260         /* check if the tag is correct */
3261         r = IXMLDOMElement_get_tagName( element, &tag );
3262         ok( r == S_OK, "couldn't get tag name\n");
3263         ok( tag != NULL, "tag was null\n");
3264         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
3265         SysFreeString( tag );
3266     }
3267
3268     if (element)
3269         IXMLDOMElement_Release( element );
3270     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
3271
3272     free_bstrs();
3273 }
3274
3275 typedef struct {
3276     DOMNodeType type;
3277     REFIID iid;
3278 } refcount_test_t;
3279
3280 static const refcount_test_t refcount_test[] = {
3281     { NODE_ELEMENT,                &IID_IXMLDOMElement },
3282     { NODE_ATTRIBUTE,              &IID_IXMLDOMAttribute },
3283     { NODE_TEXT,                   &IID_IXMLDOMText },
3284     { NODE_CDATA_SECTION,          &IID_IXMLDOMCDATASection },
3285     { NODE_ENTITY_REFERENCE,       &IID_IXMLDOMEntityReference },
3286     { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
3287     { NODE_COMMENT,                &IID_IXMLDOMComment },
3288     { NODE_DOCUMENT_FRAGMENT,      &IID_IXMLDOMDocumentFragment },
3289     { NODE_INVALID,                &IID_NULL }
3290 };
3291
3292 static void test_refs(void)
3293 {
3294     IXMLDOMImplementation *impl, *impl2;
3295     IXMLDOMElement *element, *elem2;
3296     IXMLDOMNodeList *node_list = NULL;
3297     IXMLDOMNode *node, *node2, *node3;
3298     const refcount_test_t *ptr;
3299     IXMLDOMDocument *doc;
3300     IUnknown *unk, *unk2;
3301     VARIANT_BOOL b;
3302     HRESULT hr;
3303     LONG ref;
3304
3305     doc = create_document(&IID_IXMLDOMDocument);
3306     if (!doc) return;
3307
3308     ptr = refcount_test;
3309     while (ptr->type != NODE_INVALID)
3310     {
3311         IUnknown *node_typed, *node_typed2;
3312         IDispatchEx *dispex, *dispex2;
3313         IDispatch *disp, *disp2;
3314         VARIANT type;
3315
3316         V_VT(&type) = VT_I1;
3317         V_I1(&type) = ptr->type;
3318
3319         EXPECT_REF(doc, 1);
3320         hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
3321         EXPECT_HR(hr, S_OK);
3322         EXPECT_REF(doc, 1);
3323         EXPECT_REF(node, 1);
3324
3325         /* try IDispatch and IUnknown from IXMLDOMNode */
3326         hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
3327         EXPECT_HR(hr, S_OK);
3328         EXPECT_REF(unk, 2);
3329 todo_wine {
3330         EXPECT_REF(node, 1);
3331         ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
3332 }
3333         EXPECT_REF(unk, 2);
3334         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
3335         EXPECT_HR(hr, S_OK);
3336         todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
3337         EXPECT_REF(unk, 3);
3338         todo_wine EXPECT_REF(disp, 1);
3339
3340         EXPECT_REF(unk, 3);
3341         hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
3342         EXPECT_HR(hr, S_OK);
3343         todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
3344         EXPECT_REF(unk, 4);
3345         todo_wine EXPECT_REF(disp2, 1);
3346
3347         IDispatch_Release(disp);
3348         IDispatch_Release(disp2);
3349
3350         /* get IXMLDOMNode from this IUnknown */
3351         EXPECT_REF(unk, 2);
3352         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
3353         EXPECT_HR(hr, S_OK);
3354         todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
3355         EXPECT_REF(unk, 3);
3356         todo_wine EXPECT_REF(node2, 1);
3357
3358         EXPECT_REF(unk, 3);
3359         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
3360         EXPECT_HR(hr, S_OK);
3361         todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
3362         EXPECT_REF(unk, 4);
3363         todo_wine EXPECT_REF(node3, 1);
3364
3365         IXMLDOMNode_Release(node2);
3366         IXMLDOMNode_Release(node3);
3367
3368         /* try IDispatchEx from IUnknown */
3369         EXPECT_REF(unk, 2);
3370         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
3371         EXPECT_HR(hr, S_OK);
3372         ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
3373         EXPECT_REF(unk, 3);
3374         todo_wine EXPECT_REF(dispex, 1);
3375
3376         EXPECT_REF(unk, 3);
3377         hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
3378         EXPECT_HR(hr, S_OK);
3379         todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
3380         EXPECT_REF(unk, 4);
3381         todo_wine EXPECT_REF(dispex2, 1);
3382
3383         IDispatchEx_Release(dispex);
3384         IDispatchEx_Release(dispex2);
3385
3386         /* try corresponding IXMLDOM* */
3387         EXPECT_REF(unk, 2);
3388         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
3389         EXPECT_HR(hr, S_OK);
3390         EXPECT_REF(unk, 3);
3391         hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
3392         EXPECT_HR(hr, S_OK);
3393         EXPECT_REF(unk, 4);
3394         todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
3395         IUnknown_Release(node_typed);
3396         IUnknown_Release(node_typed2);
3397
3398         /* try invalid IXMLDOM* */
3399         hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
3400         EXPECT_HR(hr, E_NOINTERFACE);
3401
3402         IUnknown_Release(unk);
3403
3404         EXPECT_REF(node, 1);
3405         hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
3406         EXPECT_HR(hr, S_OK);
3407         EXPECT_REF(node, 2);
3408         ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
3409
3410         EXPECT_REF(node, 2);
3411         hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
3412         EXPECT_HR(hr, S_OK);
3413         EXPECT_REF(node, 3);
3414 todo_wine {
3415         EXPECT_REF(node_typed, 2);
3416         ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
3417 }
3418         IUnknown_Release(node_typed);
3419
3420         IXMLDOMNode_Release(node2);
3421         IXMLDOMNode_Release(node);
3422
3423         ptr++;
3424     }
3425
3426     EXPECT_REF(doc, 1);
3427     ref = IXMLDOMDocument_Release(doc);
3428     ok( ref == 0, "ref %d\n", ref);
3429
3430     /* check IUnknown after releasing DOM iface */
3431     doc = create_document(&IID_IXMLDOMDocument);
3432     EXPECT_REF(doc, 1);
3433     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3434     EXPECT_HR(hr, S_OK);
3435 todo_wine {
3436     EXPECT_REF(unk, 3);
3437     EXPECT_REF(doc, 1);
3438 }
3439     IXMLDOMDocument_Release(doc);
3440     EXPECT_REF(unk, 1);
3441     IUnknown_Release(unk);
3442
3443     doc = create_document(&IID_IXMLDOMDocument);
3444     if (!doc) return;
3445
3446     EXPECT_REF(doc, 1);
3447     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3448     EXPECT_HR(hr, S_OK);
3449 todo_wine {
3450     EXPECT_REF(unk, 3);
3451     EXPECT_REF(doc, 1);
3452 }
3453     IUnknown_Release(unk);
3454
3455     /* IXMLDOMImplementation */
3456     EXPECT_REF(doc, 1);
3457     hr = IXMLDOMDocument_get_implementation(doc, &impl);
3458     EXPECT_HR(hr, S_OK);
3459     EXPECT_REF(doc, 1);
3460     EXPECT_REF(impl, 1);
3461     hr = IXMLDOMDocument_get_implementation(doc, &impl2);
3462     EXPECT_HR(hr, S_OK);
3463     EXPECT_REF(doc, 1);
3464     EXPECT_REF(impl2, 1);
3465     ok(impl != impl2, "got %p, %p\n", impl, impl2);
3466     IXMLDOMImplementation_Release(impl);
3467     IXMLDOMImplementation_Release(impl2);
3468
3469     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3470     EXPECT_HR(hr, S_OK);
3471     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3472
3473     EXPECT_REF(doc, 1);
3474     IXMLDOMDocument_AddRef( doc );
3475     EXPECT_REF(doc, 2);
3476     IXMLDOMDocument_AddRef( doc );
3477     EXPECT_REF(doc, 3);
3478
3479     IXMLDOMDocument_Release( doc );
3480     IXMLDOMDocument_Release( doc );
3481
3482     EXPECT_REF(doc, 1);
3483     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
3484     EXPECT_HR(hr, S_OK);
3485 todo_wine {
3486     EXPECT_REF(unk, 3);
3487     EXPECT_REF(doc, 1);
3488 }
3489     hr = IXMLDOMDocument_get_documentElement(doc, &element);
3490     EXPECT_HR(hr, S_OK);
3491 todo_wine {
3492     EXPECT_REF(doc, 1);
3493     EXPECT_REF(element, 2);
3494 }
3495     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
3496     EXPECT_HR(hr, S_OK);
3497
3498 todo_wine {
3499     EXPECT_REF(doc, 1);
3500     EXPECT_REF(element, 2);
3501     EXPECT_REF(elem2, 2);
3502 }
3503     IXMLDOMElement_AddRef(element);
3504     todo_wine EXPECT_REF(element, 3);
3505     IXMLDOMElement_Release(element);
3506
3507     /* get IUnknown from a node doesn't touch node instance refcount */
3508     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3509     EXPECT_HR(hr, S_OK);
3510     EXPECT_REF(element, 2);
3511 todo_wine {
3512     EXPECT_REF(unk, 4);
3513     EXPECT_REF(elem2, 2);
3514 }
3515     hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
3516     EXPECT_HR(hr, S_OK);
3517 todo_wine {
3518     EXPECT_REF(unk, 5);
3519     EXPECT_REF(unk2, 5);
3520 }
3521     EXPECT_REF(element, 2);
3522     EXPECT_REF(elem2, 2);
3523
3524     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
3525
3526     IUnknown_Release(unk);
3527     IUnknown_Release(unk2);
3528
3529     /* IUnknown refcount is not affected by node refcount */
3530     todo_wine EXPECT_REF(unk2, 3);
3531     IXMLDOMElement_AddRef(elem2);
3532     todo_wine EXPECT_REF(unk2, 3);
3533     IXMLDOMElement_Release(elem2);
3534
3535     IXMLDOMElement_Release(elem2);
3536     todo_wine EXPECT_REF(unk2, 2);
3537
3538     hr = IXMLDOMElement_get_childNodes( element, &node_list );
3539     EXPECT_HR(hr, S_OK);
3540
3541     todo_wine EXPECT_REF(element, 2);
3542     EXPECT_REF(node_list, 1);
3543
3544     hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3545     EXPECT_HR(hr, S_OK);
3546     EXPECT_REF(node_list, 1);
3547     EXPECT_REF(node, 1);
3548
3549     hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
3550     EXPECT_HR(hr, S_OK);
3551     EXPECT_REF(node_list, 1);
3552     EXPECT_REF(node2, 1);
3553
3554     ref = IXMLDOMNode_Release( node );
3555     ok( ref == 0, "ref %d\n", ref );
3556     ref = IXMLDOMNode_Release( node2 );
3557     ok( ref == 0, "ref %d\n", ref );
3558
3559     ref = IXMLDOMNodeList_Release( node_list );
3560     ok( ref == 0, "ref %d\n", ref );
3561
3562     ok( node != node2, "node %p node2 %p\n", node, node2 );
3563
3564     ref = IXMLDOMDocument_Release( doc );
3565     todo_wine ok( ref == 0, "ref %d\n", ref );
3566
3567     todo_wine EXPECT_REF(element, 2);
3568
3569     /* IUnknown must be unique however we obtain it */
3570     hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
3571     EXPECT_HR(hr, S_OK);
3572     EXPECT_REF(element, 2);
3573     hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
3574     EXPECT_HR(hr, S_OK);
3575     todo_wine EXPECT_REF(element, 2);
3576     hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
3577     EXPECT_HR(hr, S_OK);
3578     todo_wine EXPECT_REF(element, 2);
3579     ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
3580     todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
3581
3582     IUnknown_Release( unk2 );
3583     IUnknown_Release( unk );
3584     IXMLDOMNode_Release( node );
3585     todo_wine EXPECT_REF(element, 2);
3586
3587     IXMLDOMElement_Release( element );
3588
3589     free_bstrs();
3590 }
3591
3592 static void test_create(void)
3593 {
3594     static const WCHAR szOne[] = {'1',0};
3595     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
3596     HRESULT r;
3597     VARIANT var;
3598     BSTR str, name;
3599     IXMLDOMDocument *doc;
3600     IXMLDOMElement *element;
3601     IXMLDOMComment *comment;
3602     IXMLDOMText *text;
3603     IXMLDOMCDATASection *cdata;
3604     IXMLDOMNode *root, *node, *child;
3605     IXMLDOMNamedNodeMap *attr_map;
3606     IUnknown *unk;
3607     LONG ref;
3608     LONG num;
3609
3610     doc = create_document(&IID_IXMLDOMDocument);
3611     if (!doc) return;
3612
3613     EXPECT_REF(doc, 1);
3614
3615     /* types not supported for creation */
3616     V_VT(&var) = VT_I1;
3617     V_I1(&var) = NODE_DOCUMENT;
3618     node = (IXMLDOMNode*)0x1;
3619     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3620     ok( r == E_INVALIDARG, "returns %08x\n", r );
3621     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3622
3623     V_VT(&var) = VT_I1;
3624     V_I1(&var) = NODE_DOCUMENT_TYPE;
3625     node = (IXMLDOMNode*)0x1;
3626     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3627     ok( r == E_INVALIDARG, "returns %08x\n", r );
3628     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3629
3630     V_VT(&var) = VT_I1;
3631     V_I1(&var) = NODE_ENTITY;
3632     node = (IXMLDOMNode*)0x1;
3633     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3634     ok( r == E_INVALIDARG, "returns %08x\n", r );
3635     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3636
3637     V_VT(&var) = VT_I1;
3638     V_I1(&var) = NODE_NOTATION;
3639     node = (IXMLDOMNode*)0x1;
3640     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3641     ok( r == E_INVALIDARG, "returns %08x\n", r );
3642     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3643
3644     /* NODE_COMMENT */
3645     V_VT(&var) = VT_I1;
3646     V_I1(&var) = NODE_COMMENT;
3647     node = NULL;
3648     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3649     ok( r == S_OK, "returns %08x\n", r );
3650     ok( node != NULL, "\n");
3651
3652     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3653     ok( r == S_OK, "returns %08x\n", r );
3654     IXMLDOMNode_Release(node);
3655
3656     str = NULL;
3657     r = IXMLDOMComment_get_data(comment, &str);
3658     ok( r == S_OK, "returns %08x\n", r );
3659     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3660     IXMLDOMComment_Release(comment);
3661     SysFreeString(str);
3662
3663     node = (IXMLDOMNode*)0x1;
3664     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3665     ok( r == S_OK, "returns %08x\n", r );
3666
3667     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3668     ok( r == S_OK, "returns %08x\n", r );
3669     IXMLDOMNode_Release(node);
3670
3671     str = NULL;
3672     r = IXMLDOMComment_get_data(comment, &str);
3673     ok( r == S_OK, "returns %08x\n", r );
3674     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3675     IXMLDOMComment_Release(comment);
3676     SysFreeString(str);
3677
3678     node = (IXMLDOMNode*)0x1;
3679     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3680     ok( r == S_OK, "returns %08x\n", r );
3681
3682     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3683     ok( r == S_OK, "returns %08x\n", r );
3684     IXMLDOMNode_Release(node);
3685
3686     str = NULL;
3687     r = IXMLDOMComment_get_data(comment, &str);
3688     ok( r == S_OK, "returns %08x\n", r );
3689     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3690     IXMLDOMComment_Release(comment);
3691     SysFreeString(str);
3692
3693     /* NODE_TEXT */
3694     V_VT(&var) = VT_I1;
3695     V_I1(&var) = NODE_TEXT;
3696     node = NULL;
3697     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3698     ok( r == S_OK, "returns %08x\n", r );
3699     ok( node != NULL, "\n");
3700
3701     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3702     ok( r == S_OK, "returns %08x\n", r );
3703     IXMLDOMNode_Release(node);
3704
3705     str = NULL;
3706     r = IXMLDOMText_get_data(text, &str);
3707     ok( r == S_OK, "returns %08x\n", r );
3708     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3709     IXMLDOMText_Release(text);
3710     SysFreeString(str);
3711
3712     node = (IXMLDOMNode*)0x1;
3713     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3714     ok( r == S_OK, "returns %08x\n", r );
3715
3716     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3717     ok( r == S_OK, "returns %08x\n", r );
3718     IXMLDOMNode_Release(node);
3719
3720     str = NULL;
3721     r = IXMLDOMText_get_data(text, &str);
3722     ok( r == S_OK, "returns %08x\n", r );
3723     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3724     IXMLDOMText_Release(text);
3725     SysFreeString(str);
3726
3727     node = (IXMLDOMNode*)0x1;
3728     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3729     ok( r == S_OK, "returns %08x\n", r );
3730
3731     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3732     ok( r == S_OK, "returns %08x\n", r );
3733     IXMLDOMNode_Release(node);
3734
3735     str = NULL;
3736     r = IXMLDOMText_get_data(text, &str);
3737     ok( r == S_OK, "returns %08x\n", r );
3738     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3739     IXMLDOMText_Release(text);
3740     SysFreeString(str);
3741
3742     /* NODE_CDATA_SECTION */
3743     V_VT(&var) = VT_I1;
3744     V_I1(&var) = NODE_CDATA_SECTION;
3745     node = NULL;
3746     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3747     ok( r == S_OK, "returns %08x\n", r );
3748     ok( node != NULL, "\n");
3749
3750     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3751     ok( r == S_OK, "returns %08x\n", r );
3752     IXMLDOMNode_Release(node);
3753
3754     str = NULL;
3755     r = IXMLDOMCDATASection_get_data(cdata, &str);
3756     ok( r == S_OK, "returns %08x\n", r );
3757     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3758     IXMLDOMCDATASection_Release(cdata);
3759     SysFreeString(str);
3760
3761     node = (IXMLDOMNode*)0x1;
3762     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3763     ok( r == S_OK, "returns %08x\n", r );
3764
3765     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3766     ok( r == S_OK, "returns %08x\n", r );
3767     IXMLDOMNode_Release(node);
3768
3769     str = NULL;
3770     r = IXMLDOMCDATASection_get_data(cdata, &str);
3771     ok( r == S_OK, "returns %08x\n", r );
3772     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3773     IXMLDOMCDATASection_Release(cdata);
3774     SysFreeString(str);
3775
3776     node = (IXMLDOMNode*)0x1;
3777     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3778     ok( r == S_OK, "returns %08x\n", r );
3779
3780     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3781     ok( r == S_OK, "returns %08x\n", r );
3782     IXMLDOMNode_Release(node);
3783
3784     str = NULL;
3785     r = IXMLDOMCDATASection_get_data(cdata, &str);
3786     ok( r == S_OK, "returns %08x\n", r );
3787     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3788     IXMLDOMCDATASection_Release(cdata);
3789     SysFreeString(str);
3790
3791     /* NODE_ATTRIBUTE */
3792     V_VT(&var) = VT_I1;
3793     V_I1(&var) = NODE_ATTRIBUTE;
3794     node = (IXMLDOMNode*)0x1;
3795     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3796     ok( r == E_FAIL, "returns %08x\n", r );
3797     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3798
3799     V_VT(&var) = VT_I1;
3800     V_I1(&var) = NODE_ATTRIBUTE;
3801     node = (IXMLDOMNode*)0x1;
3802     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3803     ok( r == E_FAIL, "returns %08x\n", r );
3804     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3805
3806     V_VT(&var) = VT_I1;
3807     V_I1(&var) = NODE_ATTRIBUTE;
3808     str = SysAllocString( szlc );
3809     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3810     ok( r == S_OK, "returns %08x\n", r );
3811     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3812     SysFreeString(str);
3813
3814     /* a name is required for attribute, try a BSTR with first null wchar */
3815     V_VT(&var) = VT_I1;
3816     V_I1(&var) = NODE_ATTRIBUTE;
3817     str = SysAllocString( szstr1 );
3818     str[0] = 0;
3819     node = (IXMLDOMNode*)0x1;
3820     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3821     ok( r == E_FAIL, "returns %08x\n", r );
3822     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3823     SysFreeString(str);
3824
3825     /* NODE_PROCESSING_INSTRUCTION */
3826     V_VT(&var) = VT_I1;
3827     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3828     node = (IXMLDOMNode*)0x1;
3829     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3830     ok( r == E_FAIL, "returns %08x\n", r );
3831     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3832
3833     V_VT(&var) = VT_I1;
3834     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3835     node = (IXMLDOMNode*)0x1;
3836     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3837     ok( r == E_FAIL, "returns %08x\n", r );
3838     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3839
3840     V_VT(&var) = VT_I1;
3841     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3842     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3843     ok( r == E_INVALIDARG, "returns %08x\n", r );
3844
3845     /* NODE_ENTITY_REFERENCE */
3846     V_VT(&var) = VT_I1;
3847     V_I1(&var) = NODE_ENTITY_REFERENCE;
3848     node = (IXMLDOMNode*)0x1;
3849     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3850     ok( r == E_FAIL, "returns %08x\n", r );
3851     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3852
3853     V_VT(&var) = VT_I1;
3854     V_I1(&var) = NODE_ENTITY_REFERENCE;
3855     node = (IXMLDOMNode*)0x1;
3856     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3857     ok( r == E_FAIL, "returns %08x\n", r );
3858     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3859
3860     /* NODE_ELEMENT */
3861     V_VT(&var) = VT_I1;
3862     V_I1(&var) = NODE_ELEMENT;
3863     node = (IXMLDOMNode*)0x1;
3864     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3865     ok( r == E_FAIL, "returns %08x\n", r );
3866     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3867
3868     V_VT(&var) = VT_I1;
3869     V_I1(&var) = NODE_ELEMENT;
3870     node = (IXMLDOMNode*)0x1;
3871     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3872     ok( r == E_FAIL, "returns %08x\n", r );
3873     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3874
3875     V_VT(&var) = VT_I1;
3876     V_I1(&var) = NODE_ELEMENT;
3877     str = SysAllocString( szlc );
3878     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3879     ok( r == S_OK, "returns %08x\n", r );
3880     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3881
3882     V_VT(&var) = VT_I1;
3883     V_I1(&var) = NODE_ELEMENT;
3884     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3885     ok( r == E_INVALIDARG, "returns %08x\n", r );
3886
3887     V_VT(&var) = VT_R4;
3888     V_R4(&var) = NODE_ELEMENT;
3889     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3890     ok( r == S_OK, "returns %08x\n", r );
3891     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3892
3893     V_VT(&var) = VT_BSTR;
3894     V_BSTR(&var) = SysAllocString( szOne );
3895     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3896     ok( r == S_OK, "returns %08x\n", r );
3897     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3898     VariantClear(&var);
3899
3900     V_VT(&var) = VT_BSTR;
3901     V_BSTR(&var) = SysAllocString( szOneGarbage );
3902     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3903     ok( r == E_INVALIDARG, "returns %08x\n", r );
3904     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3905     VariantClear(&var);
3906
3907     V_VT(&var) = VT_I4;
3908     V_I4(&var) = NODE_ELEMENT;
3909     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3910     ok( r == S_OK, "returns %08x\n", r );
3911
3912     EXPECT_REF(doc, 1);
3913     r = IXMLDOMDocument_appendChild( doc, node, &root );
3914     ok( r == S_OK, "returns %08x\n", r );
3915     ok( node == root, "%p %p\n", node, root );
3916     EXPECT_REF(doc, 1);
3917
3918     EXPECT_REF(node, 2);
3919
3920     ref = IXMLDOMNode_Release( node );
3921     ok(ref == 1, "ref %d\n", ref);
3922     SysFreeString( str );
3923
3924     V_VT(&var) = VT_I4;
3925     V_I4(&var) = NODE_ELEMENT;
3926     str = SysAllocString( szbs );
3927     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3928     ok( r == S_OK, "returns %08x\n", r );
3929     SysFreeString( str );
3930
3931     EXPECT_REF(node, 1);
3932
3933     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3934     ok( r == S_OK, "returns %08x\n", r );
3935
3936     EXPECT_REF(unk, 2);
3937
3938     V_VT(&var) = VT_EMPTY;
3939     child = NULL;
3940     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3941     ok( r == S_OK, "returns %08x\n", r );
3942     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3943
3944     todo_wine EXPECT_REF(unk, 4);
3945
3946     IXMLDOMNode_Release( child );
3947     IUnknown_Release( unk );
3948
3949     V_VT(&var) = VT_NULL;
3950     V_DISPATCH(&var) = (IDispatch*)node;
3951     r = IXMLDOMNode_insertBefore( root, node, var, &child );
3952     ok( r == S_OK, "returns %08x\n", r );
3953     ok( node == child, "%p %p\n", node, child );
3954     IXMLDOMNode_Release( child );
3955
3956     V_VT(&var) = VT_NULL;
3957     V_DISPATCH(&var) = (IDispatch*)node;
3958     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3959     ok( r == S_OK, "returns %08x\n", r );
3960     IXMLDOMNode_Release( node );
3961
3962     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3963     ok( r == S_OK, "returns %08x\n", r );
3964
3965     r = IXMLDOMElement_get_attributes( element, &attr_map );
3966     ok( r == S_OK, "returns %08x\n", r );
3967     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3968     ok( r == S_OK, "returns %08x\n", r );
3969     ok( num == 0, "num %d\n", num );
3970     IXMLDOMNamedNodeMap_Release( attr_map );
3971
3972     V_VT(&var) = VT_BSTR;
3973     V_BSTR(&var) = SysAllocString( szstr1 );
3974     name = SysAllocString( szdl );
3975     r = IXMLDOMElement_setAttribute( element, name, var );
3976     ok( r == S_OK, "returns %08x\n", r );
3977     r = IXMLDOMElement_get_attributes( element, &attr_map );
3978     ok( r == S_OK, "returns %08x\n", r );
3979     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3980     ok( r == S_OK, "returns %08x\n", r );
3981     ok( num == 1, "num %d\n", num );
3982     IXMLDOMNamedNodeMap_Release( attr_map );
3983     VariantClear(&var);
3984
3985     V_VT(&var) = VT_BSTR;
3986     V_BSTR(&var) = SysAllocString( szstr2 );
3987     r = IXMLDOMElement_setAttribute( element, name, var );
3988     ok( r == S_OK, "returns %08x\n", r );
3989     r = IXMLDOMElement_get_attributes( element, &attr_map );
3990     ok( r == S_OK, "returns %08x\n", r );
3991     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3992     ok( r == S_OK, "returns %08x\n", r );
3993     ok( num == 1, "num %d\n", num );
3994     IXMLDOMNamedNodeMap_Release( attr_map );
3995     VariantClear(&var);
3996     r = IXMLDOMElement_getAttribute( element, name, &var );
3997     ok( r == S_OK, "returns %08x\n", r );
3998     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3999     VariantClear(&var);
4000     SysFreeString(name);
4001
4002     V_VT(&var) = VT_BSTR;
4003     V_BSTR(&var) = SysAllocString( szstr1 );
4004     name = SysAllocString( szlc );
4005     r = IXMLDOMElement_setAttribute( element, name, var );
4006     ok( r == S_OK, "returns %08x\n", r );
4007     r = IXMLDOMElement_get_attributes( element, &attr_map );
4008     ok( r == S_OK, "returns %08x\n", r );
4009     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
4010     ok( r == S_OK, "returns %08x\n", r );
4011     ok( num == 2, "num %d\n", num );
4012     IXMLDOMNamedNodeMap_Release( attr_map );
4013     VariantClear(&var);
4014     SysFreeString(name);
4015
4016     V_VT(&var) = VT_I4;
4017     V_I4(&var) = 10;
4018     name = SysAllocString( szbs );
4019     r = IXMLDOMElement_setAttribute( element, name, var );
4020     ok( r == S_OK, "returns %08x\n", r );
4021     VariantClear(&var);
4022     r = IXMLDOMElement_getAttribute( element, name, &var );
4023     ok( r == S_OK, "returns %08x\n", r );
4024     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
4025     VariantClear(&var);
4026     SysFreeString(name);
4027
4028     /* Create an Attribute */
4029     V_VT(&var) = VT_I4;
4030     V_I4(&var) = NODE_ATTRIBUTE;
4031     str = SysAllocString( szAttribute );
4032     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
4033     ok( r == S_OK, "returns %08x\n", r );
4034     ok( node != NULL, "node was null\n");
4035     SysFreeString(str);
4036
4037     IXMLDOMElement_Release( element );
4038     IXMLDOMNode_Release( root );
4039     IXMLDOMDocument_Release( doc );
4040 }
4041
4042 static void test_getElementsByTagName(void)
4043 {
4044     IXMLDOMNodeList *node_list;
4045     IXMLDOMDocument *doc;
4046     IXMLDOMElement *elem;
4047     WCHAR buff[100];
4048     VARIANT_BOOL b;
4049     HRESULT r;
4050     LONG len;
4051     BSTR str;
4052
4053     doc = create_document(&IID_IXMLDOMDocument);
4054     if (!doc) return;
4055
4056     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4057     ok( r == S_OK, "loadXML failed\n");
4058     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4059
4060     str = SysAllocString( szstar );
4061
4062     /* null arguments cases */
4063     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
4064     ok( r == E_INVALIDARG, "ret %08x\n", r );
4065     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
4066     ok( r == E_INVALIDARG, "ret %08x\n", r );
4067
4068     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
4069     ok( r == S_OK, "ret %08x\n", r );
4070     r = IXMLDOMNodeList_get_length( node_list, &len );
4071     ok( r == S_OK, "ret %08x\n", r );
4072     ok( len == 6, "len %d\n", len );
4073
4074     IXMLDOMNodeList_Release( node_list );
4075     SysFreeString( str );
4076
4077     /* broken query BSTR */
4078     memcpy(&buff[2], szstar, sizeof(szstar));
4079     /* just a big length */
4080     *(DWORD*)buff = 0xf0f0;
4081     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
4082     ok( r == S_OK, "ret %08x\n", r );
4083     r = IXMLDOMNodeList_get_length( node_list, &len );
4084     ok( r == S_OK, "ret %08x\n", r );
4085     ok( len == 6, "len %d\n", len );
4086     IXMLDOMNodeList_Release( node_list );
4087
4088     str = SysAllocString( szbs );
4089     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
4090     ok( r == S_OK, "ret %08x\n", r );
4091     r = IXMLDOMNodeList_get_length( node_list, &len );
4092     ok( r == S_OK, "ret %08x\n", r );
4093     ok( len == 1, "len %d\n", len );
4094     IXMLDOMNodeList_Release( node_list );
4095     SysFreeString( str );
4096
4097     str = SysAllocString( szdl );
4098     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
4099     ok( r == S_OK, "ret %08x\n", r );
4100     r = IXMLDOMNodeList_get_length( node_list, &len );
4101     ok( r == S_OK, "ret %08x\n", r );
4102     ok( len == 0, "len %d\n", len );
4103     IXMLDOMNodeList_Release( node_list );
4104     SysFreeString( str );
4105
4106     str = SysAllocString( szstr1 );
4107     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
4108     ok( r == S_OK, "ret %08x\n", r );
4109     r = IXMLDOMNodeList_get_length( node_list, &len );
4110     ok( r == S_OK, "ret %08x\n", r );
4111     ok( len == 0, "len %d\n", len );
4112     IXMLDOMNodeList_Release( node_list );
4113     SysFreeString( str );
4114
4115     /* test for element */
4116     r = IXMLDOMDocument_get_documentElement(doc, &elem);
4117     ok( r == S_OK, "ret %08x\n", r );
4118
4119     str = SysAllocString( szstar );
4120
4121     /* null arguments cases */
4122     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
4123     ok( r == E_INVALIDARG, "ret %08x\n", r );
4124     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
4125     ok( r == E_INVALIDARG, "ret %08x\n", r );
4126
4127     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
4128     ok( r == S_OK, "ret %08x\n", r );
4129     r = IXMLDOMNodeList_get_length( node_list, &len );
4130     ok( r == S_OK, "ret %08x\n", r );
4131     ok( len == 5, "len %d\n", len );
4132     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
4133     SysFreeString( str );
4134
4135     /* broken query BSTR */
4136     memcpy(&buff[2], szstar, sizeof(szstar));
4137     /* just a big length */
4138     *(DWORD*)buff = 0xf0f0;
4139     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
4140     ok( r == S_OK, "ret %08x\n", r );
4141     r = IXMLDOMNodeList_get_length( node_list, &len );
4142     ok( r == S_OK, "ret %08x\n", r );
4143     ok( len == 5, "len %d\n", len );
4144     IXMLDOMNodeList_Release( node_list );
4145
4146     IXMLDOMElement_Release(elem);
4147
4148     IXMLDOMDocument_Release( doc );
4149
4150     free_bstrs();
4151 }
4152
4153 static void test_get_text(void)
4154 {
4155     HRESULT r;
4156     BSTR str;
4157     VARIANT_BOOL b;
4158     IXMLDOMDocument *doc;
4159     IXMLDOMNode *node, *node2, *node3;
4160     IXMLDOMNode *nodeRoot;
4161     IXMLDOMNodeList *node_list;
4162     IXMLDOMNamedNodeMap *node_map;
4163     LONG len;
4164
4165     doc = create_document(&IID_IXMLDOMDocument);
4166     if (!doc) return;
4167
4168     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4169     ok( r == S_OK, "loadXML failed\n");
4170     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4171
4172     str = SysAllocString( szbs );
4173     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
4174     ok( r == S_OK, "ret %08x\n", r );
4175     SysFreeString(str);
4176
4177     /* Test to get all child node text. */
4178     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
4179     ok( r == S_OK, "ret %08x\n", r );
4180     if(r == S_OK)
4181     {
4182         r = IXMLDOMNode_get_text( nodeRoot, &str );
4183         ok( r == S_OK, "ret %08x\n", r );
4184         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
4185         SysFreeString(str);
4186
4187         IXMLDOMNode_Release(nodeRoot);
4188     }
4189
4190     r = IXMLDOMNodeList_get_length( node_list, NULL );
4191     ok( r == E_INVALIDARG, "ret %08x\n", r );
4192
4193     r = IXMLDOMNodeList_get_length( node_list, &len );
4194     ok( r == S_OK, "ret %08x\n", r );
4195     ok( len == 1, "expect 1 got %d\n", len );
4196
4197     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
4198     ok( r == E_INVALIDARG, "ret %08x\n", r );
4199
4200     r = IXMLDOMNodeList_nextNode( node_list, NULL );
4201     ok( r == E_INVALIDARG, "ret %08x\n", r );
4202
4203     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
4204     ok( r == S_OK, "ret %08x\n", r );
4205     IXMLDOMNodeList_Release( node_list );
4206
4207     /* Invalid output parameter*/
4208     r = IXMLDOMNode_get_text( node, NULL );
4209     ok( r == E_INVALIDARG, "ret %08x\n", r );
4210
4211     r = IXMLDOMNode_get_text( node, &str );
4212     ok( r == S_OK, "ret %08x\n", r );
4213     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
4214     SysFreeString(str);
4215
4216     r = IXMLDOMNode_get_attributes( node, &node_map );
4217     ok( r == S_OK, "ret %08x\n", r );
4218
4219     str = SysAllocString( szvr );
4220     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
4221     ok( r == S_OK, "ret %08x\n", r );
4222     SysFreeString(str);
4223
4224     r = IXMLDOMNode_get_text( node2, &str );
4225     ok( r == S_OK, "ret %08x\n", r );
4226     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4227     SysFreeString(str);
4228
4229     r = IXMLDOMNode_get_firstChild( node2, &node3 );
4230     ok( r == S_OK, "ret %08x\n", r );
4231
4232     r = IXMLDOMNode_get_text( node3, &str );
4233     ok( r == S_OK, "ret %08x\n", r );
4234     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
4235     SysFreeString(str);
4236
4237
4238     IXMLDOMNode_Release( node3 );
4239     IXMLDOMNode_Release( node2 );
4240     IXMLDOMNamedNodeMap_Release( node_map );
4241     IXMLDOMNode_Release( node );
4242     IXMLDOMDocument_Release( doc );
4243
4244     free_bstrs();
4245 }
4246
4247 static void test_get_childNodes(void)
4248 {
4249     IXMLDOMNodeList *node_list, *node_list2;
4250     IEnumVARIANT *enum1, *enum2, *enum3;
4251     VARIANT_BOOL b;
4252     IXMLDOMDocument *doc;
4253     IXMLDOMNode *node, *node2;
4254     IXMLDOMElement *element;
4255     IUnknown *unk1, *unk2;
4256     HRESULT hr;
4257     VARIANT v;
4258     BSTR str;
4259     LONG len;
4260
4261     doc = create_document(&IID_IXMLDOMDocument);
4262     if (!doc) return;
4263
4264     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4265     EXPECT_HR(hr, S_OK);
4266     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4267
4268     hr = IXMLDOMDocument_get_documentElement( doc, &element );
4269     EXPECT_HR(hr, S_OK);
4270
4271     hr = IXMLDOMElement_get_childNodes( element, &node_list );
4272     EXPECT_HR(hr, S_OK);
4273
4274     hr = IXMLDOMNodeList_get_length( node_list, &len );
4275     EXPECT_HR(hr, S_OK);
4276     ok( len == 4, "len %d\n", len);
4277
4278     /* refcount tests for IEnumVARIANT support */
4279     EXPECT_REF(node_list, 1);
4280     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
4281     EXPECT_HR(hr, S_OK);
4282     EXPECT_REF(node_list, 1);
4283     EXPECT_REF(enum1, 2);
4284
4285     EXPECT_REF(node_list, 1);
4286     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
4287     EXPECT_HR(hr, S_OK);
4288     EXPECT_REF(node_list, 1);
4289     ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
4290     IEnumVARIANT_Release(enum2);
4291
4292     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
4293     EXPECT_HR(hr, S_OK);
4294     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
4295     EXPECT_HR(hr, S_OK);
4296     EXPECT_REF(node_list, 3);
4297     EXPECT_REF(enum1, 2);
4298     ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
4299     IUnknown_Release(unk1);
4300     IUnknown_Release(unk2);
4301
4302     EXPECT_REF(node_list, 1);
4303     hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
4304     EXPECT_HR(hr, S_OK);
4305     EXPECT_REF(node_list, 2);
4306     EXPECT_REF(enum2, 1);
4307     ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
4308
4309     /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
4310     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
4311     EXPECT_HR(hr, S_OK);
4312     hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
4313     EXPECT_HR(hr, S_OK);
4314     EXPECT_REF(node_list, 3);
4315     EXPECT_REF(enum2, 2);
4316     ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
4317     IUnknown_Release(unk1);
4318     IUnknown_Release(unk2);
4319
4320     hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
4321     EXPECT_HR(hr, S_OK);
4322     ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
4323     IEnumVARIANT_Release(enum3);
4324     IEnumVARIANT_Release(enum2);
4325
4326     /* iteration tests */
4327     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
4328     EXPECT_HR(hr, S_OK);
4329     hr = IXMLDOMNode_get_nodeName(node, &str);
4330     EXPECT_HR(hr, S_OK);
4331     ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
4332     SysFreeString(str);
4333     IXMLDOMNode_Release(node);
4334
4335     hr = IXMLDOMNodeList_nextNode(node_list, &node);
4336     EXPECT_HR(hr, S_OK);
4337     hr = IXMLDOMNode_get_nodeName(node, &str);
4338     EXPECT_HR(hr, S_OK);
4339     ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
4340     SysFreeString(str);
4341     IXMLDOMNode_Release(node);
4342
4343     V_VT(&v) = VT_EMPTY;
4344     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
4345     EXPECT_HR(hr, S_OK);
4346     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
4347     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
4348     EXPECT_HR(hr, S_OK);
4349     hr = IXMLDOMNode_get_nodeName(node, &str);
4350     EXPECT_HR(hr, S_OK);
4351     ok(!lstrcmpW(str, _bstr_("bs")), "got node name %s\n", wine_dbgstr_w(str));
4352     SysFreeString(str);
4353     IXMLDOMNode_Release(node);
4354     VariantClear(&v);
4355
4356     hr = IXMLDOMNodeList_nextNode(node_list, &node);
4357     EXPECT_HR(hr, S_OK);
4358     hr = IXMLDOMNode_get_nodeName(node, &str);
4359     EXPECT_HR(hr, S_OK);
4360     ok(!lstrcmpW(str, _bstr_("pr")), "got %s\n", wine_dbgstr_w(str));
4361     SysFreeString(str);
4362     IXMLDOMNode_Release(node);
4363
4364     IEnumVARIANT_Release(enum1);
4365
4366     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
4367     EXPECT_HR(hr, S_OK);
4368
4369     hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
4370     EXPECT_HR(hr, S_OK);
4371
4372     hr = IXMLDOMNodeList_get_length( node_list2, &len );
4373     EXPECT_HR(hr, S_OK);
4374     ok( len == 0, "len %d\n", len);
4375
4376     hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
4377     EXPECT_HR(hr, S_FALSE);
4378
4379     IXMLDOMNodeList_Release( node_list2 );
4380     IXMLDOMNode_Release( node );
4381     IXMLDOMNodeList_Release( node_list );
4382     IXMLDOMElement_Release( element );
4383
4384     /* test for children of <?xml ..?> node */
4385     hr = IXMLDOMDocument_get_firstChild(doc, &node);
4386     EXPECT_HR(hr, S_OK);
4387
4388     str = NULL;
4389     hr = IXMLDOMNode_get_nodeName(node, &str);
4390     EXPECT_HR(hr, S_OK);
4391     ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
4392     SysFreeString(str);
4393
4394     /* it returns empty but valid node list */
4395     node_list = (void*)0xdeadbeef;
4396     hr = IXMLDOMNode_get_childNodes(node, &node_list);
4397     EXPECT_HR(hr, S_OK);
4398
4399     len = -1;
4400     hr = IXMLDOMNodeList_get_length(node_list, &len);
4401     EXPECT_HR(hr, S_OK);
4402     ok(len == 0, "got %d\n", len);
4403
4404     IXMLDOMNodeList_Release( node_list );
4405     IXMLDOMNode_Release(node);
4406
4407     IXMLDOMDocument_Release( doc );
4408     free_bstrs();
4409 }
4410
4411 static void test_get_firstChild(void)
4412 {
4413     static WCHAR xmlW[] = {'x','m','l',0};
4414     IXMLDOMDocument *doc;
4415     IXMLDOMNode *node;
4416     VARIANT_BOOL b;
4417     HRESULT r;
4418     BSTR str;
4419
4420     doc = create_document(&IID_IXMLDOMDocument);
4421     if (!doc) return;
4422
4423     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4424     ok( r == S_OK, "loadXML failed\n");
4425     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4426
4427     r = IXMLDOMDocument_get_firstChild( doc, &node );
4428     ok( r == S_OK, "ret %08x\n", r);
4429
4430     r = IXMLDOMNode_get_nodeName( node, &str );
4431     ok( r == S_OK, "ret %08x\n", r);
4432
4433     ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
4434
4435     SysFreeString(str);
4436     IXMLDOMNode_Release( node );
4437     IXMLDOMDocument_Release( doc );
4438
4439     free_bstrs();
4440 }
4441
4442 static void test_get_lastChild(void)
4443 {
4444     static WCHAR lcW[] = {'l','c',0};
4445     static WCHAR foW[] = {'f','o',0};
4446     IXMLDOMDocument *doc;
4447     IXMLDOMNode *node, *child;
4448     VARIANT_BOOL b;
4449     HRESULT r;
4450     BSTR str;
4451
4452     doc = create_document(&IID_IXMLDOMDocument);
4453     if (!doc) return;
4454
4455     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4456     ok( r == S_OK, "loadXML failed\n");
4457     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4458
4459     r = IXMLDOMDocument_get_lastChild( doc, &node );
4460     ok( r == S_OK, "ret %08x\n", r);
4461
4462     r = IXMLDOMNode_get_nodeName( node, &str );
4463     ok( r == S_OK, "ret %08x\n", r);
4464
4465     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
4466     SysFreeString(str);
4467
4468     r = IXMLDOMNode_get_lastChild( node, &child );
4469     ok( r == S_OK, "ret %08x\n", r);
4470
4471     r = IXMLDOMNode_get_nodeName( child, &str );
4472     ok( r == S_OK, "ret %08x\n", r);
4473
4474     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
4475     SysFreeString(str);
4476
4477     IXMLDOMNode_Release( child );
4478     IXMLDOMNode_Release( node );
4479     IXMLDOMDocument_Release( doc );
4480
4481     free_bstrs();
4482 }
4483
4484 static void test_removeChild(void)
4485 {
4486     HRESULT r;
4487     VARIANT_BOOL b;
4488     IXMLDOMDocument *doc;
4489     IXMLDOMElement *element, *lc_element;
4490     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
4491     IXMLDOMNodeList *root_list, *fo_list;
4492
4493     doc = create_document(&IID_IXMLDOMDocument);
4494     if (!doc) return;
4495
4496     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4497     ok( r == S_OK, "loadXML failed\n");
4498     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4499
4500     r = IXMLDOMDocument_get_documentElement( doc, &element );
4501     ok( r == S_OK, "ret %08x\n", r);
4502     todo_wine EXPECT_REF(element, 2);
4503
4504     r = IXMLDOMElement_get_childNodes( element, &root_list );
4505     ok( r == S_OK, "ret %08x\n", r);
4506     EXPECT_REF(root_list, 1);
4507
4508     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4509     ok( r == S_OK, "ret %08x\n", r);
4510     EXPECT_REF(fo_node, 1);
4511
4512     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4513     ok( r == S_OK, "ret %08x\n", r);
4514     EXPECT_REF(fo_list, 1);
4515
4516     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4517     ok( r == S_OK, "ret %08x\n", r);
4518     EXPECT_REF(ba_node, 1);
4519
4520     /* invalid parameter: NULL ptr */
4521     removed_node = (void*)0xdeadbeef;
4522     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
4523     ok( r == E_INVALIDARG, "ret %08x\n", r );
4524     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4525
4526     /* ba_node is a descendant of element, but not a direct child. */
4527     removed_node = (void*)0xdeadbeef;
4528     EXPECT_REF(ba_node, 1);
4529     EXPECT_CHILDREN(fo_node);
4530     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
4531     ok( r == E_INVALIDARG, "ret %08x\n", r );
4532     ok( removed_node == NULL, "%p\n", removed_node );
4533     EXPECT_REF(ba_node, 1);
4534     EXPECT_CHILDREN(fo_node);
4535
4536     EXPECT_REF(ba_node, 1);
4537     EXPECT_REF(fo_node, 1);
4538     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
4539     ok( r == S_OK, "ret %08x\n", r);
4540     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
4541     EXPECT_REF(fo_node, 2);
4542     EXPECT_REF(ba_node, 1);
4543
4544     /* try removing already removed child */
4545     temp_node = (void*)0xdeadbeef;
4546     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
4547     ok( r == E_INVALIDARG, "ret %08x\n", r);
4548     ok( temp_node == NULL, "%p\n", temp_node );
4549     IXMLDOMNode_Release( fo_node );
4550
4551     /* the removed node has no parent anymore */
4552     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
4553     ok( r == S_FALSE, "ret %08x\n", r);
4554     ok( temp_node == NULL, "%p\n", temp_node );
4555
4556     IXMLDOMNode_Release( removed_node );
4557     IXMLDOMNode_Release( ba_node );
4558     IXMLDOMNodeList_Release( fo_list );
4559
4560     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4561     ok( r == S_OK, "ret %08x\n", r);
4562
4563     r = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
4564     ok( r == S_OK, "ret %08x\n", r);
4565
4566     /* MS quirk: passing wrong interface pointer works, too */
4567     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
4568     ok( r == S_OK, "ret %08x\n", r);
4569     IXMLDOMElement_Release( lc_element );
4570
4571     temp_node = (void*)0xdeadbeef;
4572     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
4573     ok( r == S_FALSE, "ret %08x\n", r);
4574     ok( temp_node == NULL, "%p\n", temp_node );
4575
4576     IXMLDOMNode_Release( lc_node );
4577     IXMLDOMNodeList_Release( root_list );
4578     IXMLDOMElement_Release( element );
4579     IXMLDOMDocument_Release( doc );
4580
4581     free_bstrs();
4582 }
4583
4584 static void test_replaceChild(void)
4585 {
4586     HRESULT r;
4587     VARIANT_BOOL b;
4588     IXMLDOMDocument *doc;
4589     IXMLDOMElement *element, *ba_element;
4590     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
4591     IXMLDOMNodeList *root_list, *fo_list;
4592     IUnknown * unk1, *unk2;
4593     LONG len;
4594
4595     doc = create_document(&IID_IXMLDOMDocument);
4596     if (!doc) return;
4597
4598     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4599     ok( r == S_OK, "loadXML failed\n");
4600     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4601
4602     r = IXMLDOMDocument_get_documentElement( doc, &element );
4603     ok( r == S_OK, "ret %08x\n", r);
4604
4605     r = IXMLDOMElement_get_childNodes( element, &root_list );
4606     ok( r == S_OK, "ret %08x\n", r);
4607
4608     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
4609     ok( r == S_OK, "ret %08x\n", r);
4610
4611     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
4612     ok( r == S_OK, "ret %08x\n", r);
4613
4614     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4615     ok( r == S_OK, "ret %08x\n", r);
4616
4617     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
4618     ok( r == S_OK, "ret %08x\n", r);
4619
4620     IXMLDOMNodeList_Release( fo_list );
4621
4622     /* invalid parameter: NULL ptr for element to remove */
4623     removed_node = (void*)0xdeadbeef;
4624     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
4625     ok( r == E_INVALIDARG, "ret %08x\n", r );
4626     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4627
4628     /* invalid parameter: NULL for replacement element. (Sic!) */
4629     removed_node = (void*)0xdeadbeef;
4630     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
4631     ok( r == E_INVALIDARG, "ret %08x\n", r );
4632     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
4633
4634     /* invalid parameter: OldNode is not a child */
4635     removed_node = (void*)0xdeadbeef;
4636     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
4637     ok( r == E_INVALIDARG, "ret %08x\n", r );
4638     ok( removed_node == NULL, "%p\n", removed_node );
4639     IXMLDOMNode_Release( lc_node );
4640
4641     /* invalid parameter: would create loop */
4642     removed_node = (void*)0xdeadbeef;
4643     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
4644     ok( r == E_FAIL, "ret %08x\n", r );
4645     ok( removed_node == NULL, "%p\n", removed_node );
4646
4647     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4648     ok( r == S_OK, "ret %08x\n", r );
4649
4650     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4651     ok( r == S_OK, "ret %08x\n", r );
4652
4653     /* ba_node and temp_node refer to the same node, yet they
4654        are different interface pointers */
4655     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4656     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4657     ok( r == S_OK, "ret %08x\n", r );
4658     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4659     ok( r == S_OK, "ret %08x\n", r );
4660     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4661
4662     IUnknown_Release( unk1 );
4663     IUnknown_Release( unk2 );
4664
4665     /* ba_node should have been removed from below fo_node */
4666     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4667     ok( r == S_OK, "ret %08x\n", r );
4668
4669     /* MS quirk: replaceChild also accepts elements instead of nodes */
4670     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4671     ok( r == S_OK, "ret %08x\n", r );
4672     EXPECT_REF(ba_element, 2);
4673
4674     removed_node = NULL;
4675     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4676     ok( r == S_OK, "ret %08x\n", r );
4677     ok( removed_node != NULL, "got %p\n", removed_node);
4678     EXPECT_REF(ba_element, 3);
4679     IXMLDOMElement_Release( ba_element );
4680
4681     r = IXMLDOMNodeList_get_length( fo_list, &len);
4682     ok( r == S_OK, "ret %08x\n", r );
4683     ok( len == 0, "len %d\n", len);
4684
4685     IXMLDOMNodeList_Release( fo_list );
4686
4687     IXMLDOMNode_Release(ba_node);
4688     IXMLDOMNode_Release(fo_node);
4689     IXMLDOMNode_Release(temp_node);
4690     IXMLDOMNodeList_Release( root_list );
4691     IXMLDOMElement_Release( element );
4692     IXMLDOMDocument_Release( doc );
4693
4694     free_bstrs();
4695 }
4696
4697 static void test_removeNamedItem(void)
4698 {
4699     IXMLDOMDocument *doc;
4700     IXMLDOMElement *element;
4701     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4702     IXMLDOMNodeList *root_list;
4703     IXMLDOMNamedNodeMap * pr_attrs;
4704     VARIANT_BOOL b;
4705     BSTR str;
4706     LONG len;
4707     HRESULT r;
4708
4709     doc = create_document(&IID_IXMLDOMDocument);
4710     if (!doc) return;
4711
4712     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4713     ok( r == S_OK, "loadXML failed\n");
4714     ok( b == VARIANT_TRUE, "failed to load XML string\n");
4715
4716     r = IXMLDOMDocument_get_documentElement( doc, &element );
4717     ok( r == S_OK, "ret %08x\n", r);
4718
4719     r = IXMLDOMElement_get_childNodes( element, &root_list );
4720     ok( r == S_OK, "ret %08x\n", r);
4721
4722     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4723     ok( r == S_OK, "ret %08x\n", r);
4724
4725     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4726     ok( r == S_OK, "ret %08x\n", r);
4727
4728     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4729     ok( r == S_OK, "ret %08x\n", r);
4730     ok( len == 3, "length %d\n", len);
4731
4732     removed_node = (void*)0xdeadbeef;
4733     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4734     ok ( r == E_INVALIDARG, "ret %08x\n", r);
4735     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4736
4737     removed_node = (void*)0xdeadbeef;
4738     str = SysAllocString(szvr);
4739     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4740     ok ( r == S_OK, "ret %08x\n", r);
4741
4742     removed_node2 = (void*)0xdeadbeef;
4743     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4744     ok ( r == S_FALSE, "ret %08x\n", r);
4745     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4746
4747     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4748     ok( r == S_OK, "ret %08x\n", r);
4749     ok( len == 2, "length %d\n", len);
4750
4751     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4752     ok ( r == S_OK, "ret %08x\n", r);
4753     IXMLDOMNode_Release(removed_node);
4754
4755     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4756     ok( r == S_OK, "ret %08x\n", r);
4757     ok( len == 3, "length %d\n", len);
4758
4759     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4760     ok ( r == S_OK, "ret %08x\n", r);
4761
4762     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4763     ok( r == S_OK, "ret %08x\n", r);
4764     ok( len == 2, "length %d\n", len);
4765
4766     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4767     ok ( r == S_FALSE, "ret %08x\n", r);
4768
4769     SysFreeString(str);
4770
4771     IXMLDOMNamedNodeMap_Release( pr_attrs );
4772     IXMLDOMNode_Release( pr_node );
4773     IXMLDOMNodeList_Release( root_list );
4774     IXMLDOMElement_Release( element );
4775     IXMLDOMDocument_Release( doc );
4776
4777     free_bstrs();
4778 }
4779
4780 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4781 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4782                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4783                                     DWORD expected2)
4784 {
4785     DWORD enabled, supported;
4786     HRESULT hr;
4787
4788     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4789     if (result == result2)
4790         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4791     else
4792         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4793            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4794
4795     supported = enabled = 0xCAFECAFE;
4796     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4797     ok(hr == S_OK, "ret %08x\n", hr );
4798     if (expected == expected2)
4799         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4800     else
4801         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4802            "Expected %08x, got %08x\n", expected2, enabled);
4803
4804     /* reset the safety options */
4805
4806     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4807             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4808             0);
4809     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4810
4811     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4812     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4813     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4814 }
4815
4816 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4817 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4818 {
4819     DWORD enabled = 0, supported = 0;
4820     HRESULT hr;
4821
4822     /* get */
4823     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4824     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4825     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4826     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4827
4828     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4829     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4830     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4831        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4832         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4833              "got %08x\n", supported);
4834     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4835
4836     /* set -- individual flags */
4837
4838     test_IObjectSafety_set(safety, S_OK, S_OK,
4839         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4840         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4841
4842     test_IObjectSafety_set(safety, S_OK, S_OK,
4843         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4844         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4845
4846     test_IObjectSafety_set(safety, S_OK, S_OK,
4847         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4848         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4849
4850     /* set INTERFACE_USES_DISPEX  */
4851
4852     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4853         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4854         0, 0);
4855
4856     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4857         INTERFACE_USES_DISPEX, 0,
4858         0, 0);
4859
4860     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4861         0, INTERFACE_USES_DISPEX,
4862         0, 0);
4863
4864     /* set option masking */
4865
4866     test_IObjectSafety_set(safety, S_OK, S_OK,
4867         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4868         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4869         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4870         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4871
4872     test_IObjectSafety_set(safety, S_OK, S_OK,
4873         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4874         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4875         INTERFACESAFE_FOR_UNTRUSTED_DATA,
4876         INTERFACESAFE_FOR_UNTRUSTED_DATA);
4877
4878     test_IObjectSafety_set(safety, S_OK, S_OK,
4879         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4880         INTERFACE_USES_SECURITY_MANAGER,
4881         0,
4882         0);
4883
4884     /* set -- inheriting previous settings */
4885
4886     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4887                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4888                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4889     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4890     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4891     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4892     ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4893     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4894        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4895         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4896              "got %08x\n", supported);
4897
4898     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4899                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
4900                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
4901     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4902     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4903     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4904     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4905                        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4906                        "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4907     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4908        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4909         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4910              "got %08x\n", supported);
4911 }
4912
4913 static void test_XMLHTTP(void)
4914 {
4915     static const char bodyA[] = "mode=Test";
4916     static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
4917     static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
4918     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
4919     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
4920
4921     IXMLHttpRequest *xhr;
4922     IObjectSafety *safety;
4923     IObjectWithSite *obj_site, *obj_site2;
4924     BSTR bstrResponse, str, str1;
4925     VARIANT varbody, varbody_ref;
4926     VARIANT dummy;
4927     VARIANT async;
4928     LONG state, status, bound;
4929     IDispatch *event;
4930     void *ptr;
4931     HRESULT hr;
4932     HGLOBAL g;
4933
4934     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
4935         &IID_IXMLHttpRequest, (void**)&xhr);
4936     if (FAILED(hr))
4937     {
4938         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
4939         return;
4940     }
4941
4942     VariantInit(&dummy);
4943     V_VT(&dummy) = VT_ERROR;
4944     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
4945     VariantInit(&async);
4946     V_VT(&async) = VT_BOOL;
4947     V_BOOL(&async) = VARIANT_FALSE;
4948
4949     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
4950     EXPECT_HR(hr, S_OK);
4951
4952     hr = IXMLHttpRequest_abort(xhr);
4953     EXPECT_HR(hr, S_OK);
4954
4955     V_VT(&varbody) = VT_I2;
4956     V_I2(&varbody) = 1;
4957     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
4958     EXPECT_HR(hr, E_PENDING);
4959     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4960     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4961
4962     V_VT(&varbody) = VT_I2;
4963     V_I2(&varbody) = 1;
4964     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
4965     EXPECT_HR(hr, E_PENDING);
4966     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
4967     ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
4968
4969     /* send before open */
4970     hr = IXMLHttpRequest_send(xhr, dummy);
4971     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4972
4973     /* initial status code */
4974     hr = IXMLHttpRequest_get_status(xhr, NULL);
4975     EXPECT_HR(hr, E_INVALIDARG);
4976
4977     status = 0xdeadbeef;
4978     hr = IXMLHttpRequest_get_status(xhr, &status);
4979     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
4980     ok(status == 0xdeadbeef, "got %d\n", status);
4981
4982     hr = IXMLHttpRequest_get_statusText(xhr, &str);
4983     ok(hr == E_FAIL, "got 0x%08x\n", hr);
4984
4985     /* invalid parameters */
4986     hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
4987     EXPECT_HR(hr, E_INVALIDARG);
4988
4989     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
4990     EXPECT_HR(hr, E_INVALIDARG);
4991
4992     hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
4993     EXPECT_HR(hr, E_INVALIDARG);
4994
4995     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
4996     EXPECT_HR(hr, E_INVALIDARG);
4997
4998     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
4999     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
5000
5001     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
5002     EXPECT_HR(hr, E_INVALIDARG);
5003
5004     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
5005     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
5006
5007     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
5008     EXPECT_HR(hr, E_INVALIDARG);
5009
5010     state = -1;
5011     hr = IXMLHttpRequest_get_readyState(xhr, &state);
5012     EXPECT_HR(hr, S_OK);
5013     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
5014
5015     event = create_dispevent();
5016
5017     EXPECT_REF(event, 1);
5018     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
5019     EXPECT_HR(hr, S_OK);
5020     EXPECT_REF(event, 2);
5021
5022     g_unexpectedcall = g_expectedcall = 0;
5023
5024     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
5025     EXPECT_HR(hr, S_OK);
5026
5027     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
5028     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
5029
5030     /* status code after ::open() */
5031     status = 0xdeadbeef;
5032     hr = IXMLHttpRequest_get_status(xhr, &status);
5033     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
5034     ok(status == 0xdeadbeef, "got %d\n", status);
5035
5036     state = -1;
5037     hr = IXMLHttpRequest_get_readyState(xhr, &state);
5038     EXPECT_HR(hr, S_OK);
5039     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
5040
5041     hr = IXMLHttpRequest_abort(xhr);
5042     EXPECT_HR(hr, S_OK);
5043
5044     state = -1;
5045     hr = IXMLHttpRequest_get_readyState(xhr, &state);
5046     EXPECT_HR(hr, S_OK);
5047     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
5048         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
5049
5050     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
5051     EXPECT_HR(hr, S_OK);
5052
5053     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
5054     EXPECT_HR(hr, S_OK);
5055
5056     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
5057     EXPECT_HR(hr, E_INVALIDARG);
5058
5059     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
5060     EXPECT_HR(hr, E_INVALIDARG);
5061
5062     V_VT(&varbody) = VT_BSTR;
5063     V_BSTR(&varbody) = _bstr_(bodyA);
5064
5065     hr = IXMLHttpRequest_send(xhr, varbody);
5066     if (hr == INET_E_RESOURCE_NOT_FOUND)
5067     {
5068         skip("No connection could be made with crossover.codeweavers.com\n");
5069         IXMLHttpRequest_Release(xhr);
5070         return;
5071     }
5072     EXPECT_HR(hr, S_OK);
5073
5074     /* response headers */
5075     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
5076     EXPECT_HR(hr, E_INVALIDARG);
5077     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
5078     EXPECT_HR(hr, S_OK);
5079     /* status line is stripped already */
5080     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
5081     ok(*str, "got empty headers\n");
5082     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
5083     EXPECT_HR(hr, S_OK);
5084     ok(str1 != str, "got %p\n", str1);
5085     SysFreeString(str1);
5086     SysFreeString(str);
5087
5088     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
5089     EXPECT_HR(hr, E_INVALIDARG);
5090     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
5091     EXPECT_HR(hr, E_INVALIDARG);
5092     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
5093     EXPECT_HR(hr, S_OK);
5094     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
5095     SysFreeString(str);
5096
5097     /* status code after ::send() */
5098     status = 0xdeadbeef;
5099     hr = IXMLHttpRequest_get_status(xhr, &status);
5100     EXPECT_HR(hr, S_OK);
5101     ok(status == 200, "got %d\n", status);
5102
5103     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
5104     EXPECT_HR(hr, E_INVALIDARG);
5105
5106     hr = IXMLHttpRequest_get_statusText(xhr, &str);
5107     EXPECT_HR(hr, S_OK);
5108     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
5109     SysFreeString(str);
5110
5111     /* another ::send() after completed request */
5112     V_VT(&varbody) = VT_BSTR;
5113     V_BSTR(&varbody) = _bstr_(bodyA);
5114
5115     hr = IXMLHttpRequest_send(xhr, varbody);
5116     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
5117
5118     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
5119     EXPECT_HR(hr, S_OK);
5120     /* the server currently returns "FAILED" because the Content-Type header is
5121      * not what the server expects */
5122     if(hr == S_OK)
5123     {
5124         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
5125             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
5126         SysFreeString(bstrResponse);
5127     }
5128
5129     /* POST: VT_VARIANT|VT_BYREF body */
5130     V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
5131     V_VARIANTREF(&varbody_ref) = &varbody;
5132     hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
5133     EXPECT_HR(hr, S_OK);
5134     hr = IXMLHttpRequest_send(xhr, varbody_ref);
5135     EXPECT_HR(hr, S_OK);
5136
5137     /* GET request */
5138     hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
5139     EXPECT_HR(hr, S_OK);
5140
5141     V_VT(&varbody) = VT_EMPTY;
5142
5143     hr = IXMLHttpRequest_send(xhr, varbody);
5144     if (hr == INET_E_RESOURCE_NOT_FOUND)
5145     {
5146         skip("No connection could be made with crossover.codeweavers.com\n");
5147         IXMLHttpRequest_Release(xhr);
5148         return;
5149     }
5150     EXPECT_HR(hr, S_OK);
5151
5152     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
5153     EXPECT_HR(hr, E_INVALIDARG);
5154
5155     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
5156     EXPECT_HR(hr, S_OK);
5157     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
5158         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
5159     SysFreeString(bstrResponse);
5160
5161     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
5162     EXPECT_HR(hr, E_INVALIDARG);
5163
5164     V_VT(&varbody) = VT_EMPTY;
5165     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
5166     EXPECT_HR(hr, S_OK);
5167     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
5168     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
5169
5170     bound = -1;
5171     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
5172     EXPECT_HR(hr, S_OK);
5173     ok(bound == 0, "got %d, expected zero bound\n", bound);
5174
5175     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
5176     EXPECT_HR(hr, S_OK);
5177     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
5178     SafeArrayUnaccessData(V_ARRAY(&varbody));
5179
5180     VariantClear(&varbody);
5181
5182     /* get_responseStream */
5183     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
5184     EXPECT_HR(hr, E_INVALIDARG);
5185
5186     V_VT(&varbody) = VT_EMPTY;
5187     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
5188     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
5189     EXPECT_HR(hr, S_OK);
5190     EXPECT_REF(V_UNKNOWN(&varbody), 1);
5191
5192     g = NULL;
5193     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
5194     EXPECT_HR(hr, S_OK);
5195     ok(g != NULL, "got %p\n", g);
5196
5197     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
5198     EXPECT_HR(hr, S_OK);
5199     if(hr == S_OK)
5200     {
5201         test_IObjectSafety_common(safety);
5202         IObjectSafety_Release(safety);
5203     }
5204
5205     IDispatch_Release(event);
5206
5207     /* interaction with object site */
5208     EXPECT_REF(xhr, 1);
5209     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
5210     EXPECT_HR(hr, S_OK);
5211 todo_wine {
5212     EXPECT_REF(xhr, 1);
5213     EXPECT_REF(obj_site, 1);
5214 }
5215
5216     hr = IObjectWithSite_SetSite(obj_site, NULL);
5217     ok(hr == S_OK, "got 0x%08x\n", hr);
5218
5219     IObjectWithSite_AddRef(obj_site);
5220 todo_wine {
5221     EXPECT_REF(obj_site, 2);
5222     EXPECT_REF(xhr, 1);
5223 }
5224     IObjectWithSite_Release(obj_site);
5225
5226     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
5227     EXPECT_HR(hr, S_OK);
5228 todo_wine {
5229     EXPECT_REF(xhr, 1);
5230     EXPECT_REF(obj_site, 1);
5231     EXPECT_REF(obj_site2, 1);
5232     ok(obj_site != obj_site2, "expected new instance\n");
5233 }
5234     SET_EXPECT(site_qi_IServiceProvider);
5235     SET_EXPECT(sp_queryservice_SID_SBindHost);
5236     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5237     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
5238     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
5239     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
5240
5241     /* calls to IHTMLDocument2 */
5242     SET_EXPECT(htmldoc2_get_all);
5243     SET_EXPECT(collection_get_length);
5244     SET_EXPECT(htmldoc2_get_url);
5245
5246     SET_EXPECT(site_qi_IXMLDOMDocument);
5247     SET_EXPECT(site_qi_IOleClientSite);
5248
5249     hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
5250     EXPECT_HR(hr, S_OK);
5251
5252     CHECK_CALLED(site_qi_IServiceProvider);
5253 todo_wine
5254     CHECK_CALLED(sp_queryservice_SID_SBindHost);
5255     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5256 todo_wine {
5257     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
5258     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
5259     /* this one isn't very reliable
5260     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
5261
5262     CHECK_CALLED(htmldoc2_get_all);
5263     CHECK_CALLED(collection_get_length);
5264     CHECK_CALLED(htmldoc2_get_url);
5265
5266     CHECK_CALLED(site_qi_IXMLDOMDocument);
5267     CHECK_CALLED(site_qi_IOleClientSite);
5268 }
5269     IObjectWithSite_Release(obj_site);
5270
5271     /* try to set site another time */
5272
5273     /* to be removed once IObjectWithSite is properly separated */
5274     SET_EXPECT(site_qi_IServiceProvider);
5275     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5276
5277     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5278     EXPECT_HR(hr, S_OK);
5279
5280     todo_wine EXPECT_REF(xhr, 1);
5281     IXMLHttpRequest_Release(xhr);
5282
5283     /* still works after request is released */
5284
5285     /* to be removed once IObjectWithSite is properly separated */
5286     SET_EXPECT(site_qi_IServiceProvider);
5287     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
5288
5289     hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
5290     EXPECT_HR(hr, S_OK);
5291     IObjectWithSite_Release(obj_site2);
5292
5293     free_bstrs();
5294 }
5295
5296 static void test_IXMLDOMDocument2(void)
5297 {
5298     static const WCHAR emptyW[] = {0};
5299     IXMLDOMDocument2 *doc2, *dtddoc2;
5300     IXMLDOMDocument *doc;
5301     IXMLDOMParseError* err;
5302     IDispatchEx *dispex;
5303     VARIANT_BOOL b;
5304     VARIANT var;
5305     HRESULT r;
5306     LONG res;
5307
5308     doc = create_document(&IID_IXMLDOMDocument);
5309     if (!doc) return;
5310
5311     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
5312     if (!dtddoc2)
5313     {
5314         IXMLDOMDocument_Release(doc);
5315         return;
5316     }
5317
5318     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
5319     ok( r == S_OK, "ret %08x\n", r );
5320     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
5321
5322     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
5323     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
5324     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5325
5326     err = NULL;
5327     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
5328     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5329     ok(err != NULL, "expected a pointer\n");
5330     if (err)
5331     {
5332         res = 0;
5333         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5334         /* XML_E_NOTWF */
5335         ok(res == E_XML_NOTWF, "got %08x\n", res);
5336         IXMLDOMParseError_Release(err);
5337     }
5338
5339     r = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b );
5340     ok( r == S_OK, "loadXML failed\n");
5341     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5342
5343     ole_check(IXMLDOMDocument_get_readyState(doc, &res));
5344     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
5345
5346     err = NULL;
5347     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
5348     ok(err != NULL, "expected a pointer\n");
5349     if (err)
5350     {
5351         res = 0;
5352         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5353         /* XML_E_NODTD */
5354         ok(res == E_XML_NODTD, "got %08x\n", res);
5355         IXMLDOMParseError_Release(err);
5356     }
5357
5358     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
5359     ok( r == S_OK, "ret %08x\n", r );
5360     if(r == S_OK)
5361     {
5362         IDispatchEx_Release(dispex);
5363     }
5364
5365     /* we will check if the variant got cleared */
5366     IXMLDOMDocument2_AddRef(doc2);
5367     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
5368
5369     V_VT(&var) = VT_UNKNOWN;
5370     V_UNKNOWN(&var) = (IUnknown *)doc2;
5371
5372     /* invalid calls */
5373     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
5374     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
5375     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
5376
5377     /* valid call */
5378     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5379     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5380     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5381     V_VT(&var) = VT_R4;
5382
5383     /* the variant didn't get cleared*/
5384     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
5385
5386     /* setProperty tests */
5387     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
5388     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
5389     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
5390     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5391     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5392     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
5393
5394     V_VT(&var) = VT_BSTR;
5395     V_BSTR(&var) = SysAllocString(emptyW);
5396     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5397     ok(r == S_OK, "got 0x%08x\n", r);
5398     VariantClear(&var);
5399
5400     V_VT(&var) = VT_I2;
5401     V_I2(&var) = 0;
5402     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
5403     ok(r == E_FAIL, "got 0x%08x\n", r);
5404
5405     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
5406     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
5407     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5408     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
5409
5410     IXMLDOMDocument2_Release( doc2 );
5411     IXMLDOMDocument_Release( doc );
5412
5413     /* DTD validation */
5414     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
5415     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
5416     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5417     err = NULL;
5418     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
5419     ok(err != NULL, "expected pointer\n");
5420     if (err)
5421     {
5422         res = 0;
5423         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
5424         ok(res == 0, "got %08x\n", res);
5425         IXMLDOMParseError_Release(err);
5426     }
5427
5428     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
5429     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5430     err = NULL;
5431     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5432     ok(err != NULL, "expected pointer\n");
5433     if (err)
5434     {
5435         res = 0;
5436         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5437         /* XML_ELEMENT_UNDECLARED */
5438         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
5439         IXMLDOMParseError_Release(err);
5440     }
5441
5442     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
5443     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5444     err = NULL;
5445     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5446     ok(err != NULL, "expected pointer\n");
5447     if (err)
5448     {
5449         res = 0;
5450         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5451         /* XML_ELEMENT_ID_NOT_FOUND */
5452         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
5453         IXMLDOMParseError_Release(err);
5454     }
5455
5456     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
5457     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5458     err = NULL;
5459     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5460     ok(err != NULL, "expected pointer\n");
5461     if (err)
5462     {
5463         res = 0;
5464         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5465         /* XML_EMPTY_NOT_ALLOWED */
5466         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
5467         IXMLDOMParseError_Release(err);
5468     }
5469
5470     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
5471     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5472     err = NULL;
5473     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5474     ok(err != NULL, "expected pointer\n");
5475     if (err)
5476     {
5477         res = 0;
5478         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5479         /* XML_ROOT_NAME_MISMATCH */
5480         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
5481         IXMLDOMParseError_Release(err);
5482     }
5483
5484     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
5485     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5486     err = NULL;
5487     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5488     ok(err != NULL, "expected pointer\n");
5489     if (err)
5490     {
5491         res = 0;
5492         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5493         /* XML_INVALID_CONTENT */
5494         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
5495         IXMLDOMParseError_Release(err);
5496     }
5497
5498     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
5499     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5500     err = NULL;
5501     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5502     ok(err != NULL, "expected pointer\n");
5503     if (err)
5504     {
5505         res = 0;
5506         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5507         /* XML_ATTRIBUTE_NOT_DEFINED */
5508         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
5509         IXMLDOMParseError_Release(err);
5510     }
5511
5512     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
5513     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5514     err = NULL;
5515     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5516     ok(err != NULL, "expected pointer\n");
5517     if (err)
5518     {
5519         res = 0;
5520         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5521         /* XML_ATTRIBUTE_FIXED */
5522         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
5523         IXMLDOMParseError_Release(err);
5524     }
5525
5526     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
5527     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5528     err = NULL;
5529     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5530     ok(err != NULL, "expected pointer\n");
5531     if (err)
5532     {
5533         res = 0;
5534         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5535         /* XML_ATTRIBUTE_VALUE */
5536         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
5537         IXMLDOMParseError_Release(err);
5538     }
5539
5540     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
5541     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5542     err = NULL;
5543     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5544     ok(err != NULL, "expected pointer\n");
5545     if (err)
5546     {
5547         res = 0;
5548         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5549         /* XML_ILLEGAL_TEXT */
5550         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
5551         IXMLDOMParseError_Release(err);
5552     }
5553
5554     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
5555     ok( b == VARIANT_TRUE, "failed to load XML string\n");
5556     err = NULL;
5557     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
5558     ok(err != NULL, "expected pointer\n");
5559     if (err)
5560     {
5561         res = 0;
5562         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
5563         /* XML_REQUIRED_ATTRIBUTE_MISSING */
5564         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
5565         IXMLDOMParseError_Release(err);
5566     }
5567
5568     IXMLDOMDocument2_Release( dtddoc2 );
5569     free_bstrs();
5570 }
5571
5572 #define helper_ole_check(expr) { \
5573     HRESULT r = expr; \
5574     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
5575 }
5576
5577 #define helper_expect_list_and_release(list, expstr) { \
5578     char *str = list_to_string(list); \
5579     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
5580     if (list) IXMLDOMNodeList_Release(list); \
5581 }
5582
5583 #define helper_expect_bstr_and_release(bstr, str) { \
5584     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
5585        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
5586     SysFreeString(bstr); \
5587 }
5588
5589 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
5590 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
5591 {
5592     IXMLDOMNode *node1, *node2;
5593     IXMLDOMNodeList *list;
5594     BSTR bstr;
5595
5596     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5597     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5598     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5599     helper_ole_check(IXMLDOMNodeList_reset(list));
5600     helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
5601
5602     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5603     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");
5604     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5605     if (str)
5606     {
5607         helper_expect_bstr_and_release(bstr, str);
5608     }
5609     else
5610     {
5611         helper_expect_bstr_and_release(bstr, "This is a description.");
5612     }
5613     IXMLDOMNode_Release(node1);
5614
5615     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5616     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");
5617     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5618     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5619     IXMLDOMNode_Release(node2);
5620 }
5621
5622 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
5623 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
5624 {
5625     IXMLDOMNode *node1, *node2;
5626     IXMLDOMNodeList *list;
5627     BSTR bstr;
5628
5629     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
5630     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
5631     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
5632     helper_ole_check(IXMLDOMNodeList_reset(list));
5633     helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
5634
5635     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
5636     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");
5637     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
5638     if (str)
5639     {
5640         helper_expect_bstr_and_release(bstr, str);
5641     }
5642     else
5643     {
5644         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
5645     }
5646     IXMLDOMNode_Release(node1);
5647
5648     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
5649     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");
5650     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
5651     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
5652     IXMLDOMNode_Release(node2);
5653 }
5654
5655 static void test_whitespace(void)
5656 {
5657     VARIANT_BOOL b;
5658     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
5659
5660     doc1 = create_document(&IID_IXMLDOMDocument2);
5661     doc2 = create_document(&IID_IXMLDOMDocument2);
5662     if (!doc1 || !doc2) return;
5663
5664     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
5665     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5666     ok(b == VARIANT_FALSE, "expected false\n");
5667     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5668     ok(b == VARIANT_TRUE, "expected true\n");
5669
5670     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5671     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5672     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5673     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5674
5675     /* switch to XPath */
5676     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5677     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5678
5679     check_ws_ignored(doc1, NULL);
5680     check_ws_preserved(doc2, NULL);
5681
5682     /* new instances copy the property */
5683     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
5684     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
5685
5686     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5687     ok(b == VARIANT_FALSE, "expected false\n");
5688     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5689     ok(b == VARIANT_TRUE, "expected true\n");
5690
5691     check_ws_ignored(doc3, NULL);
5692     check_ws_preserved(doc4, NULL);
5693
5694     /* setting after loading xml affects trimming of leading/trailing ws only */
5695     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
5696     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
5697
5698     /* the trailing "\n            " isn't there, because it was ws-only node */
5699     check_ws_ignored(doc1, "\n                This is a description. ");
5700     check_ws_preserved(doc2, "This is a description.");
5701
5702     /* it takes effect on reload */
5703     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
5704     ok(b == VARIANT_TRUE, "expected true\n");
5705     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
5706     ok(b == VARIANT_FALSE, "expected false\n");
5707
5708     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
5709     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5710     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
5711     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5712
5713     check_ws_preserved(doc1, NULL);
5714     check_ws_ignored(doc2, NULL);
5715
5716     /* other instances follow suit */
5717     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
5718     ok(b == VARIANT_TRUE, "expected true\n");
5719     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
5720     ok(b == VARIANT_FALSE, "expected false\n");
5721
5722     check_ws_preserved(doc3, NULL);
5723     check_ws_ignored(doc4, NULL);
5724
5725     IXMLDOMDocument2_Release(doc1);
5726     IXMLDOMDocument2_Release(doc2);
5727     IXMLDOMDocument2_Release(doc3);
5728     IXMLDOMDocument2_Release(doc4);
5729     free_bstrs();
5730 }
5731
5732 typedef struct {
5733     const GUID *clsid;
5734     const char *name;
5735     const char *ns;
5736     HRESULT hr;
5737 } selection_ns_t;
5738
5739 /* supposed to be tested with szExampleXML */
5740 static const selection_ns_t selection_ns_data[] = {
5741     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5742     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5743     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5744     { &CLSID_DOMDocument,   "CLSID_DOMDocument",   "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
5745
5746     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5747     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5748     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5749     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2",  "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
5750
5751     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5752     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5753     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5754     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
5755
5756     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5757     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5758     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5759     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
5760
5761     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5762     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5763     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
5764     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
5765
5766     { NULL }
5767 };
5768
5769 static void test_XPath(void)
5770 {
5771     const selection_ns_t *ptr = selection_ns_data;
5772     VARIANT var;
5773     VARIANT_BOOL b;
5774     IXMLDOMDocument2 *doc;
5775     IXMLDOMDocument *doc2;
5776     IXMLDOMNode *rootNode;
5777     IXMLDOMNode *elem1Node;
5778     IXMLDOMNode *node;
5779     IXMLDOMNodeList *list;
5780     IXMLDOMElement *elem;
5781     IXMLDOMAttribute *attr;
5782     DOMNodeType type;
5783     HRESULT hr;
5784     LONG len;
5785     BSTR str;
5786
5787     doc = create_document(&IID_IXMLDOMDocument2);
5788     if (!doc) return;
5789
5790     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5791     EXPECT_HR(hr, S_OK);
5792     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5793
5794     /* switch to XPath */
5795     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
5796
5797     /* some simple queries*/
5798     EXPECT_REF(doc, 1);
5799     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5800     EXPECT_HR(hr, S_OK);
5801     EXPECT_REF(doc, 1);
5802     EXPECT_LIST_LEN(list, 1);
5803
5804     EXPECT_REF(list, 1);
5805     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5806     EXPECT_HR(hr, S_OK);
5807     EXPECT_REF(list, 1);
5808     EXPECT_REF(rootNode, 1);
5809
5810     hr = IXMLDOMNodeList_reset(list);
5811     EXPECT_HR(hr, S_OK);
5812     expect_list_and_release(list, "E2.D1");
5813
5814 if (0)
5815 {
5816     /* namespace:: axis test is disabled until namespace definitions
5817        are supported as attribute nodes, currently it's another node type */
5818     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5819     EXPECT_HR(hr, S_OK);
5820     len = -1;
5821     hr = IXMLDOMNodeList_get_length(list, &len);
5822     EXPECT_HR(hr, S_OK);
5823     ok(len == 2, "got %d\n", len);
5824
5825     hr = IXMLDOMNodeList_nextNode(list, &node);
5826     EXPECT_HR(hr, S_OK);
5827     type = NODE_INVALID;
5828     hr = IXMLDOMNode_get_nodeType(node, &type);
5829     EXPECT_HR(hr, S_OK);
5830     ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5831     IXMLDOMNode_Release(node);
5832
5833     IXMLDOMNodeList_Release(list);
5834 }
5835
5836     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
5837     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5838
5839     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
5840     expect_list_and_release(list, "E3.E2.E2.D1");
5841
5842     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
5843     /* using get_item for query results advances the position */
5844     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
5845     expect_node(node, "E2.E2.D1");
5846     IXMLDOMNode_Release(node);
5847     ole_check(IXMLDOMNodeList_nextNode(list, &node));
5848     expect_node(node, "E4.E2.D1");
5849     IXMLDOMNode_Release(node);
5850     ole_check(IXMLDOMNodeList_reset(list));
5851     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5852
5853     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
5854     expect_list_and_release(list, "E2.D1");
5855
5856     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
5857     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
5858     ole_check(IXMLDOMNodeList_reset(list));
5859     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5860
5861     /* select an attribute */
5862     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
5863     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5864
5865     /* would evaluate to a number */
5866     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
5867     /* would evaluate to a boolean */
5868     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
5869     /* would evaluate to a string */
5870     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
5871
5872     /* no results */
5873     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
5874     expect_list_and_release(list, "");
5875     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("elem//c"), &list));
5876     expect_list_and_release(list, "");
5877     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem[4]"), &list));
5878     expect_list_and_release(list, "");
5879     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
5880     expect_list_and_release(list, "");
5881
5882     /* foo undeclared in document node */
5883     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5884     /* undeclared in <root> node */
5885     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
5886     /* undeclared in <elem> node */
5887     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
5888     /* but this trick can be used */
5889     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
5890     expect_list_and_release(list, "E3.E4.E2.D1");
5891
5892     /* it has to be declared in SelectionNamespaces */
5893     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5894         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
5895
5896     /* now the namespace can be used */
5897     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
5898     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5899     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
5900     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5901     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
5902     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5903     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
5904     expect_list_and_release(list, "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
5905
5906     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5907     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5908         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
5909
5910     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5911
5912     VariantInit(&var);
5913     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5914     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5915     if (V_VT(&var) == VT_BSTR)
5916         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5917
5918     /* extra attributes - same thing*/
5919     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5920         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5921     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5922
5923     IXMLDOMNode_Release(rootNode);
5924     IXMLDOMNode_Release(elem1Node);
5925
5926     /* alter document with already built list */
5927     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5928     EXPECT_HR(hr, S_OK);
5929     EXPECT_LIST_LEN(list, 1);
5930
5931     hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5932     EXPECT_HR(hr, S_OK);
5933     EXPECT_REF(rootNode, 1);
5934     EXPECT_REF(doc, 1);
5935
5936     hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5937     EXPECT_HR(hr, S_OK);
5938     IXMLDOMNode_Release(rootNode);
5939
5940     EXPECT_LIST_LEN(list, 1);
5941
5942     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5943     EXPECT_HR(hr, S_OK);
5944     EXPECT_REF(rootNode, 1);
5945
5946     IXMLDOMNodeList_Release(list);
5947
5948     hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5949     EXPECT_HR(hr, S_OK);
5950     ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5951     SysFreeString(str);
5952     IXMLDOMNode_Release(rootNode);
5953
5954     /* alter node from list and get it another time */
5955     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5956     EXPECT_HR(hr, S_OK);
5957     ok(b == VARIANT_TRUE, "failed to load XML string\n");
5958
5959     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5960     EXPECT_HR(hr, S_OK);
5961     EXPECT_LIST_LEN(list, 1);
5962
5963     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5964     EXPECT_HR(hr, S_OK);
5965
5966     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5967     EXPECT_HR(hr, S_OK);
5968
5969     V_VT(&var) = VT_I2;
5970     V_I2(&var) = 1;
5971     hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5972     EXPECT_HR(hr, S_OK);
5973     IXMLDOMElement_Release(elem);
5974     IXMLDOMNode_Release(rootNode);
5975
5976     /* now check attribute to be present */
5977     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5978     EXPECT_HR(hr, S_OK);
5979
5980     hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5981     EXPECT_HR(hr, S_OK);
5982
5983     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5984     EXPECT_HR(hr, S_OK);
5985     IXMLDOMAttribute_Release(attr);
5986
5987     IXMLDOMElement_Release(elem);
5988     IXMLDOMNode_Release(rootNode);
5989
5990     /* and now check for attribute in original document */
5991     hr = IXMLDOMDocument2_get_documentElement(doc, &elem);
5992     EXPECT_HR(hr, S_OK);
5993
5994     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5995     EXPECT_HR(hr, S_OK);
5996     IXMLDOMAttribute_Release(attr);
5997
5998     IXMLDOMElement_Release(elem);
5999
6000     /* attach node from list to another document */
6001     doc2 = create_document(&IID_IXMLDOMDocument);
6002
6003     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
6004     EXPECT_HR(hr, S_OK);
6005     ok(b == VARIANT_TRUE, "failed to load XML string\n");
6006
6007     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
6008     EXPECT_HR(hr, S_OK);
6009     EXPECT_LIST_LEN(list, 1);
6010
6011     hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
6012     EXPECT_HR(hr, S_OK);
6013     EXPECT_REF(rootNode, 1);
6014
6015     hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
6016     EXPECT_HR(hr, S_OK);
6017     EXPECT_REF(rootNode, 1);
6018     EXPECT_REF(doc2, 1);
6019     EXPECT_REF(list, 1);
6020
6021     EXPECT_LIST_LEN(list, 1);
6022
6023     IXMLDOMNode_Release(rootNode);
6024     IXMLDOMNodeList_Release(list);
6025     IXMLDOMDocument_Release(doc2);
6026     IXMLDOMDocument2_Release(doc);
6027
6028     while (ptr->clsid)
6029     {
6030         hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
6031         if (hr != S_OK)
6032         {
6033             win_skip("can't create instance of %s\n", ptr->name);
6034             ptr++;
6035             continue;
6036         }
6037
6038         hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
6039         EXPECT_HR(hr, S_OK);
6040         ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
6041
6042         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
6043         EXPECT_HR(hr, S_OK);
6044
6045         V_VT(&var) = VT_BSTR;
6046         V_BSTR(&var) = _bstr_(ptr->ns);
6047
6048         hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
6049         ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
6050
6051         V_VT(&var) = VT_EMPTY;
6052         hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
6053         EXPECT_HR(hr, S_OK);
6054         ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
6055         ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
6056         VariantClear(&var);
6057
6058         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
6059         EXPECT_HR(hr, S_OK);
6060         if (hr == S_OK)
6061             expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
6062
6063         IXMLDOMDocument2_Release(doc);
6064         ptr++;
6065         free_bstrs();
6066     }
6067
6068     free_bstrs();
6069 }
6070
6071 static void test_cloneNode(void )
6072 {
6073     IXMLDOMDocument *doc, *doc2;
6074     VARIANT_BOOL b;
6075     IXMLDOMNodeList *pList;
6076     IXMLDOMNamedNodeMap *mapAttr;
6077     LONG length, length1;
6078     LONG attr_cnt, attr_cnt1;
6079     IXMLDOMNode *node, *attr;
6080     IXMLDOMNode *node_clone;
6081     IXMLDOMNode *node_first;
6082     HRESULT hr;
6083
6084     doc = create_document(&IID_IXMLDOMDocument);
6085     if (!doc) return;
6086
6087     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
6088     ok(b == VARIANT_TRUE, "failed to load XML string\n");
6089
6090     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc/pr"), &node);
6091     ok( hr == S_OK, "ret %08x\n", hr );
6092     ok( node != NULL, "node %p\n", node );
6093
6094     /* Check invalid parameter */
6095     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
6096     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
6097
6098     /* All Children */
6099     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
6100     ok( hr == S_OK, "ret %08x\n", hr );
6101     ok( node_clone != NULL, "node %p\n", node );
6102
6103     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
6104     ok( hr == S_OK, "ret %08x\n", hr );
6105     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
6106     ok( hr == S_OK, "ret %08x\n", hr );
6107     IXMLDOMDocument_Release(doc2);
6108     IXMLDOMNode_Release(node_first);
6109
6110     hr = IXMLDOMNode_get_childNodes(node, &pList);
6111     ok( hr == S_OK, "ret %08x\n", hr );
6112     length = 0;
6113     hr = IXMLDOMNodeList_get_length(pList, &length);
6114     ok( hr == S_OK, "ret %08x\n", hr );
6115     ok(length == 1, "got %d\n", length);
6116     IXMLDOMNodeList_Release(pList);
6117
6118     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
6119     ok( hr == S_OK, "ret %08x\n", hr );
6120     attr_cnt = 0;
6121     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
6122     ok( hr == S_OK, "ret %08x\n", hr );
6123     ok(attr_cnt == 3, "got %d\n", attr_cnt);
6124     IXMLDOMNamedNodeMap_Release(mapAttr);
6125
6126     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
6127     ok( hr == S_OK, "ret %08x\n", hr );
6128     length1 = 0;
6129     hr = IXMLDOMNodeList_get_length(pList, &length1);
6130     ok(length1 == 1, "got %d\n", length1);
6131     ok( hr == S_OK, "ret %08x\n", hr );
6132     IXMLDOMNodeList_Release(pList);
6133
6134     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
6135     ok( hr == S_OK, "ret %08x\n", hr );
6136     attr_cnt1 = 0;
6137     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
6138     ok( hr == S_OK, "ret %08x\n", hr );
6139     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
6140     /* now really get some attributes from cloned element */
6141     attr = NULL;
6142     hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr);
6143     ok(hr == S_OK, "ret %08x\n", hr);
6144     IXMLDOMNode_Release(attr);
6145     IXMLDOMNamedNodeMap_Release(mapAttr);
6146
6147     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
6148     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
6149     IXMLDOMNode_Release(node_clone);
6150
6151     /* No Children */
6152     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
6153     ok( hr == S_OK, "ret %08x\n", hr );
6154     ok( node_clone != NULL, "node %p\n", node );
6155
6156     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
6157     ok(hr == S_FALSE, "ret %08x\n", hr );
6158
6159     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
6160     ok(hr == S_OK, "ret %08x\n", hr );
6161     hr = IXMLDOMNodeList_get_length(pList, &length1);
6162     ok(hr == S_OK, "ret %08x\n", hr );
6163     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
6164     IXMLDOMNodeList_Release(pList);
6165
6166     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
6167     ok(hr == S_OK, "ret %08x\n", hr );
6168     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
6169     ok(hr == S_OK, "ret %08x\n", hr );
6170     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
6171     IXMLDOMNamedNodeMap_Release(mapAttr);
6172
6173     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
6174     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
6175     IXMLDOMNode_Release(node_clone);
6176
6177     IXMLDOMNode_Release(node);
6178     IXMLDOMDocument_Release(doc);
6179     free_bstrs();
6180 }
6181
6182 static void test_xmlTypes(void)
6183 {
6184     IXMLDOMDocument *doc;
6185     IXMLDOMElement *pRoot;
6186     HRESULT hr;
6187     IXMLDOMComment *pComment;
6188     IXMLDOMElement *pElement;
6189     IXMLDOMAttribute *pAttribute;
6190     IXMLDOMNamedNodeMap *pAttribs;
6191     IXMLDOMCDATASection *pCDataSec;
6192     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
6193     IXMLDOMDocumentFragment *pDocFrag = NULL;
6194     IXMLDOMEntityReference *pEntityRef = NULL;
6195     BSTR str;
6196     IXMLDOMNode *pNextChild;
6197     VARIANT v;
6198     LONG len = 0;
6199
6200     doc = create_document(&IID_IXMLDOMDocument);
6201     if (!doc) return;
6202
6203     pNextChild = (void*)0xdeadbeef;
6204     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
6205     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6206
6207     pNextChild = (void*)0xdeadbeef;
6208     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
6209     ok(hr == S_FALSE, "ret %08x\n", hr );
6210     ok(pNextChild == NULL, "pDocChild not NULL\n");
6211
6212     /* test previous Sibling */
6213     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
6214     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6215
6216     pNextChild = (void*)0xdeadbeef;
6217     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
6218     ok(hr == S_FALSE, "ret %08x\n", hr );
6219     ok(pNextChild == NULL, "pNextChild not NULL\n");
6220
6221     /* test get_dataType */
6222     V_VT(&v) = VT_EMPTY;
6223     hr = IXMLDOMDocument_get_dataType(doc, &v);
6224     ok(hr == S_FALSE, "ret %08x\n", hr );
6225     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
6226     VariantClear(&v);
6227
6228     /* test implementation */
6229     hr = IXMLDOMDocument_get_implementation(doc, NULL);
6230     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6231
6232     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
6233     ok(hr == S_OK, "ret %08x\n", hr );
6234     if(hr == S_OK)
6235     {
6236         VARIANT_BOOL hasFeature = VARIANT_TRUE;
6237         BSTR sEmpty = SysAllocStringLen(NULL, 0);
6238
6239         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
6240         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6241
6242         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
6243         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6244
6245         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6246         ok(hr == S_OK, "ret %08x\n", hr );
6247         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6248
6249         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
6250         ok(hr == S_OK, "ret %08x\n", hr );
6251         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
6252
6253         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
6254         ok(hr == S_OK, "ret %08x\n", hr );
6255         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
6256
6257         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
6258         ok(hr == S_OK, "ret %08x\n", hr );
6259         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6260
6261         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
6262         ok(hr == S_OK, "ret %08x\n", hr );
6263         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6264
6265         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
6266         ok(hr == S_OK, "ret %08x\n", hr );
6267         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6268
6269         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
6270         ok(hr == S_OK, "ret %08x\n", hr );
6271         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
6272
6273         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
6274         ok(hr == S_OK, "ret %08x\n", hr );
6275         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
6276
6277         SysFreeString(sEmpty);
6278         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
6279     }
6280
6281     pRoot = (IXMLDOMElement*)0x1;
6282     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
6283     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6284     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6285
6286     pRoot = (IXMLDOMElement*)0x1;
6287     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
6288     ok(hr == E_FAIL, "ret %08x\n", hr );
6289     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
6290
6291     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
6292     ok(hr == S_OK, "ret %08x\n", hr );
6293     if(hr == S_OK)
6294     {
6295         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
6296         ok(hr == S_OK, "ret %08x\n", hr );
6297         if(hr == S_OK)
6298         {
6299             /* Comment */
6300             str = SysAllocString(szComment);
6301             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
6302             SysFreeString(str);
6303             ok(hr == S_OK, "ret %08x\n", hr );
6304             if(hr == S_OK)
6305             {
6306                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
6307                 ok(hr == S_OK, "ret %08x\n", hr );
6308
6309                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
6310                 ok(hr == S_OK, "ret %08x\n", hr );
6311                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
6312                 SysFreeString(str);
6313
6314                 hr = IXMLDOMComment_get_xml(pComment, &str);
6315                 ok(hr == S_OK, "ret %08x\n", hr );
6316                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
6317                 SysFreeString(str);
6318
6319                 /* put data Tests */
6320                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
6321                 ok(hr == S_OK, "ret %08x\n", hr );
6322
6323                 /* get data Tests */
6324                 hr = IXMLDOMComment_get_data(pComment, &str);
6325                 ok(hr == S_OK, "ret %08x\n", hr );
6326                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
6327                 SysFreeString(str);
6328
6329                 /* Confirm XML text is good */
6330                 hr = IXMLDOMComment_get_xml(pComment, &str);
6331                 ok(hr == S_OK, "ret %08x\n", hr );
6332                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
6333                 SysFreeString(str);
6334
6335                 /* Confirm we get the put_data Text back */
6336                 hr = IXMLDOMComment_get_text(pComment, &str);
6337                 ok(hr == S_OK, "ret %08x\n", hr );
6338                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
6339                 SysFreeString(str);
6340
6341                 /* test length property */
6342                 hr = IXMLDOMComment_get_length(pComment, &len);
6343                 ok(hr == S_OK, "ret %08x\n", hr );
6344                 ok(len == 21, "expected 21 got %d\n", len);
6345
6346                 /* test substringData */
6347                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
6348                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6349
6350                 /* test substringData - Invalid offset */
6351                 str = (BSTR)&szElement;
6352                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
6353                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6354                 ok( str == NULL, "incorrect string\n");
6355
6356                 /* test substringData - Invalid offset */
6357                 str = (BSTR)&szElement;
6358                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
6359                 ok(hr == S_FALSE, "ret %08x\n", hr );
6360                 ok( str == NULL, "incorrect string\n");
6361
6362                 /* test substringData - Invalid size */
6363                 str = (BSTR)&szElement;
6364                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
6365                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6366                 ok( str == NULL, "incorrect string\n");
6367
6368                 /* test substringData - Invalid size */
6369                 str = (BSTR)&szElement;
6370                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
6371                 ok(hr == S_FALSE, "ret %08x\n", hr );
6372                 ok( str == NULL, "incorrect string\n");
6373
6374                 /* test substringData - Start of string */
6375                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
6376                 ok(hr == S_OK, "ret %08x\n", hr );
6377                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6378                 SysFreeString(str);
6379
6380                 /* test substringData - Middle of string */
6381                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
6382                 ok(hr == S_OK, "ret %08x\n", hr );
6383                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6384                 SysFreeString(str);
6385
6386                 /* test substringData - End of string */
6387                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
6388                 ok(hr == S_OK, "ret %08x\n", hr );
6389                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6390                 SysFreeString(str);
6391
6392                 /* test appendData */
6393                 hr = IXMLDOMComment_appendData(pComment, NULL);
6394                 ok(hr == S_OK, "ret %08x\n", hr );
6395
6396                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
6397                 ok(hr == S_OK, "ret %08x\n", hr );
6398
6399                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
6400                 ok(hr == S_OK, "ret %08x\n", hr );
6401
6402                 hr = IXMLDOMComment_get_text(pComment, &str);
6403                 ok(hr == S_OK, "ret %08x\n", hr );
6404                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6405                 SysFreeString(str);
6406
6407                 /* test insertData */
6408                 str = SysAllocStringLen(NULL, 0);
6409                 hr = IXMLDOMComment_insertData(pComment, -1, str);
6410                 ok(hr == S_OK, "ret %08x\n", hr );
6411
6412                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
6413                 ok(hr == S_OK, "ret %08x\n", hr );
6414
6415                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
6416                 ok(hr == S_OK, "ret %08x\n", hr );
6417
6418                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
6419                 ok(hr == S_OK, "ret %08x\n", hr );
6420
6421                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
6422                 ok(hr == S_OK, "ret %08x\n", hr );
6423
6424                 hr = IXMLDOMComment_insertData(pComment, 0, str);
6425                 ok(hr == S_OK, "ret %08x\n", hr );
6426                 SysFreeString(str);
6427
6428                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
6429                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6430
6431                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
6432                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6433
6434                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
6435                 ok(hr == S_OK, "ret %08x\n", hr );
6436
6437                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
6438                 ok(hr == S_OK, "ret %08x\n", hr );
6439
6440                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
6441                 ok(hr == S_OK, "ret %08x\n", hr );
6442
6443                 hr = IXMLDOMComment_get_text(pComment, &str);
6444                 ok(hr == S_OK, "ret %08x\n", hr );
6445                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6446                 SysFreeString(str);
6447
6448                 /* delete data */
6449                 /* invalid arguments */
6450                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
6451                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6452
6453                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
6454                 ok(hr == S_OK, "ret %08x\n", hr );
6455
6456                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
6457                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6458
6459                 hr = IXMLDOMComment_get_length(pComment, &len);
6460                 ok(hr == S_OK, "ret %08x\n", hr );
6461                 ok(len == 43, "expected 43 got %d\n", len);
6462
6463                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
6464                 ok(hr == S_OK, "ret %08x\n", hr );
6465
6466                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
6467                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6468
6469                 /* delete from start */
6470                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
6471                 ok(hr == S_OK, "ret %08x\n", hr );
6472
6473                 hr = IXMLDOMComment_get_length(pComment, &len);
6474                 ok(hr == S_OK, "ret %08x\n", hr );
6475                 ok(len == 38, "expected 38 got %d\n", len);
6476
6477                 hr = IXMLDOMComment_get_text(pComment, &str);
6478                 ok(hr == S_OK, "ret %08x\n", hr );
6479                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6480                 SysFreeString(str);
6481
6482                 /* delete from end */
6483                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
6484                 ok(hr == S_OK, "ret %08x\n", hr );
6485
6486                 hr = IXMLDOMComment_get_length(pComment, &len);
6487                 ok(hr == S_OK, "ret %08x\n", hr );
6488                 ok(len == 35, "expected 35 got %d\n", len);
6489
6490                 hr = IXMLDOMComment_get_text(pComment, &str);
6491                 ok(hr == S_OK, "ret %08x\n", hr );
6492                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6493                 SysFreeString(str);
6494
6495                 /* delete from inside */
6496                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
6497                 ok(hr == S_OK, "ret %08x\n", hr );
6498
6499                 hr = IXMLDOMComment_get_length(pComment, &len);
6500                 ok(hr == S_OK, "ret %08x\n", hr );
6501                 ok(len == 2, "expected 2 got %d\n", len);
6502
6503                 hr = IXMLDOMComment_get_text(pComment, &str);
6504                 ok(hr == S_OK, "ret %08x\n", hr );
6505                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6506                 SysFreeString(str);
6507
6508                 /* delete whole data ... */
6509                 hr = IXMLDOMComment_get_length(pComment, &len);
6510                 ok(hr == S_OK, "ret %08x\n", hr );
6511
6512                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6513                 ok(hr == S_OK, "ret %08x\n", hr );
6514                 /* ... and try again with empty string */
6515                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
6516                 ok(hr == S_OK, "ret %08x\n", hr );
6517
6518                 /* ::replaceData() */
6519                 V_VT(&v) = VT_BSTR;
6520                 V_BSTR(&v) = SysAllocString(szstr1);
6521                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
6522                 ok(hr == S_OK, "ret %08x\n", hr );
6523                 VariantClear(&v);
6524
6525                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
6526                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6527                 hr = IXMLDOMComment_get_text(pComment, &str);
6528                 ok(hr == S_OK, "ret %08x\n", hr );
6529                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6530                 SysFreeString(str);
6531
6532                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
6533                 ok(hr == S_OK, "ret %08x\n", hr );
6534                 hr = IXMLDOMComment_get_text(pComment, &str);
6535                 ok(hr == S_OK, "ret %08x\n", hr );
6536                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6537                 SysFreeString(str);
6538
6539                 /* NULL pointer means delete */
6540                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
6541                 ok(hr == S_OK, "ret %08x\n", hr );
6542                 hr = IXMLDOMComment_get_text(pComment, &str);
6543                 ok(hr == S_OK, "ret %08x\n", hr );
6544                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6545                 SysFreeString(str);
6546
6547                 /* empty string means delete */
6548                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
6549                 ok(hr == S_OK, "ret %08x\n", hr );
6550                 hr = IXMLDOMComment_get_text(pComment, &str);
6551                 ok(hr == S_OK, "ret %08x\n", hr );
6552                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6553                 SysFreeString(str);
6554
6555                 /* zero count means insert */
6556                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
6557                 ok(hr == S_OK, "ret %08x\n", hr );
6558                 hr = IXMLDOMComment_get_text(pComment, &str);
6559                 ok(hr == S_OK, "ret %08x\n", hr );
6560                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6561                 SysFreeString(str);
6562
6563                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
6564                 ok(hr == S_OK, "ret %08x\n", hr );
6565
6566                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
6567                 ok(hr == S_OK, "ret %08x\n", hr );
6568                 hr = IXMLDOMComment_get_text(pComment, &str);
6569                 ok(hr == S_OK, "ret %08x\n", hr );
6570                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6571                 SysFreeString(str);
6572
6573                 /* nonempty string, count greater than its length */
6574                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
6575                 ok(hr == S_OK, "ret %08x\n", hr );
6576                 hr = IXMLDOMComment_get_text(pComment, &str);
6577                 ok(hr == S_OK, "ret %08x\n", hr );
6578                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6579                 SysFreeString(str);
6580
6581                 /* nonempty string, count less than its length */
6582                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
6583                 ok(hr == S_OK, "ret %08x\n", hr );
6584                 hr = IXMLDOMComment_get_text(pComment, &str);
6585                 ok(hr == S_OK, "ret %08x\n", hr );
6586                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6587                 SysFreeString(str);
6588
6589                 IXMLDOMComment_Release(pComment);
6590             }
6591
6592             /* Element */
6593             str = SysAllocString(szElement);
6594             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
6595             SysFreeString(str);
6596             ok(hr == S_OK, "ret %08x\n", hr );
6597             if(hr == S_OK)
6598             {
6599                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
6600                 ok(hr == S_OK, "ret %08x\n", hr );
6601
6602                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
6603                 ok(hr == S_OK, "ret %08x\n", hr );
6604                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
6605                 SysFreeString(str);
6606
6607                 hr = IXMLDOMElement_get_xml(pElement, &str);
6608                 ok(hr == S_OK, "ret %08x\n", hr );
6609                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
6610                 SysFreeString(str);
6611
6612                 /* Attribute */
6613                 pAttribute = (IXMLDOMAttribute*)0x1;
6614                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
6615                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6616                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6617
6618                 pAttribute = (IXMLDOMAttribute*)0x1;
6619                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
6620                 ok(hr == E_FAIL, "ret %08x\n", hr );
6621                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
6622
6623                 str = SysAllocString(szAttribute);
6624                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
6625                 SysFreeString(str);
6626                 ok(hr == S_OK, "ret %08x\n", hr );
6627                 if(hr == S_OK)
6628                 {
6629                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
6630
6631                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
6632                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6633
6634                     pNextChild = (IXMLDOMNode *)0x1;
6635                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
6636                     ok(hr == S_FALSE, "ret %08x\n", hr );
6637                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6638
6639                     /* test Previous Sibling*/
6640                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
6641                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6642
6643                     pNextChild = (IXMLDOMNode *)0x1;
6644                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
6645                     ok(hr == S_FALSE, "ret %08x\n", hr );
6646                     ok(pNextChild == NULL, "pNextChild not NULL\n");
6647
6648                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
6649                     ok(hr == E_FAIL, "ret %08x\n", hr );
6650                     ok(pNewChild == NULL, "pNewChild not NULL\n");
6651
6652                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
6653                     ok(hr == S_OK, "ret %08x\n", hr );
6654                     if ( hr == S_OK )
6655                     {
6656                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
6657                         ok(hr == S_OK, "ret %08x\n", hr );
6658
6659                         IXMLDOMNamedNodeMap_Release(pAttribs);
6660                     }
6661
6662                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6663                     ok(hr == S_OK, "ret %08x\n", hr );
6664                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
6665                     SysFreeString(str);
6666
6667                     /* test nodeName */
6668                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
6669                     ok(hr == S_OK, "ret %08x\n", hr );
6670                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
6671                     SysFreeString(str);
6672
6673                     /* test name property */
6674                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
6675                     ok(hr == S_OK, "ret %08x\n", hr );
6676                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
6677                     SysFreeString(str);
6678
6679                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6680                     ok(hr == S_OK, "ret %08x\n", hr );
6681                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
6682                     SysFreeString(str);
6683
6684                     IXMLDOMAttribute_Release(pAttribute);
6685
6686                     /* Check Element again with the Add Attribute*/
6687                     hr = IXMLDOMElement_get_xml(pElement, &str);
6688                     ok(hr == S_OK, "ret %08x\n", hr );
6689                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
6690                     SysFreeString(str);
6691                 }
6692
6693                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6694                 ok(hr == S_OK, "ret %08x\n", hr );
6695
6696                 hr = IXMLDOMElement_get_xml(pElement, &str);
6697                 ok(hr == S_OK, "ret %08x\n", hr );
6698                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
6699                 SysFreeString(str);
6700
6701                 /* Test for reversible escaping */
6702                 str = SysAllocString( szStrangeChars );
6703                 hr = IXMLDOMElement_put_text(pElement, str);
6704                 ok(hr == S_OK, "ret %08x\n", hr );
6705                 SysFreeString( str );
6706
6707                 hr = IXMLDOMElement_get_xml(pElement, &str);
6708                 ok(hr == S_OK, "ret %08x\n", hr );
6709                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
6710                 SysFreeString(str);
6711
6712                 hr = IXMLDOMElement_get_text(pElement, &str);
6713                 ok(hr == S_OK, "ret %08x\n", hr );
6714                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6715                 SysFreeString(str);
6716
6717                 IXMLDOMElement_Release(pElement);
6718             }
6719
6720             /* CData Section */
6721             str = SysAllocString(szCData);
6722             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6723             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6724
6725             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6726             SysFreeString(str);
6727             ok(hr == S_OK, "ret %08x\n", hr );
6728             if(hr == S_OK)
6729             {
6730                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6731                 VARIANT var;
6732
6733                 VariantInit(&var);
6734
6735                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6736                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
6737
6738                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6739                 ok(hr == S_OK, "ret %08x\n", hr );
6740
6741                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6742                 ok(hr == S_OK, "ret %08x\n", hr );
6743                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
6744                 SysFreeString(str);
6745
6746                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6747                 ok(hr == S_OK, "ret %08x\n", hr );
6748                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
6749                 SysFreeString(str);
6750
6751                 /* test lastChild */
6752                 pNextChild = (IXMLDOMNode*)0x1;
6753                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6754                 ok(hr == S_FALSE, "ret %08x\n", hr );
6755                 ok(pNextChild == NULL, "pNextChild not NULL\n");
6756
6757                 /* put data Tests */
6758                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6759                 ok(hr == S_OK, "ret %08x\n", hr );
6760
6761                 /* Confirm XML text is good */
6762                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6763                 ok(hr == S_OK, "ret %08x\n", hr );
6764                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
6765                 SysFreeString(str);
6766
6767                 /* Confirm we get the put_data Text back */
6768                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6769                 ok(hr == S_OK, "ret %08x\n", hr );
6770                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6771                 SysFreeString(str);
6772
6773                 /* test length property */
6774                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6775                 ok(hr == S_OK, "ret %08x\n", hr );
6776                 ok(len == 21, "expected 21 got %d\n", len);
6777
6778                 /* test get data */
6779                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6780                 ok(hr == S_OK, "ret %08x\n", hr );
6781                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
6782                 SysFreeString(str);
6783
6784                 /* test substringData */
6785                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6786                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6787
6788                 /* test substringData - Invalid offset */
6789                 str = (BSTR)&szElement;
6790                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6791                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6792                 ok( str == NULL, "incorrect string\n");
6793
6794                 /* test substringData - Invalid offset */
6795                 str = (BSTR)&szElement;
6796                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6797                 ok(hr == S_FALSE, "ret %08x\n", hr );
6798                 ok( str == NULL, "incorrect string\n");
6799
6800                 /* test substringData - Invalid size */
6801                 str = (BSTR)&szElement;
6802                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6803                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6804                 ok( str == NULL, "incorrect string\n");
6805
6806                 /* test substringData - Invalid size */
6807                 str = (BSTR)&szElement;
6808                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6809                 ok(hr == S_FALSE, "ret %08x\n", hr );
6810                 ok( str == NULL, "incorrect string\n");
6811
6812                 /* test substringData - Start of string */
6813                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6814                 ok(hr == S_OK, "ret %08x\n", hr );
6815                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
6816                 SysFreeString(str);
6817
6818                 /* test substringData - Middle of string */
6819                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6820                 ok(hr == S_OK, "ret %08x\n", hr );
6821                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
6822                 SysFreeString(str);
6823
6824                 /* test substringData - End of string */
6825                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6826                 ok(hr == S_OK, "ret %08x\n", hr );
6827                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
6828                 SysFreeString(str);
6829
6830                 /* test appendData */
6831                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6832                 ok(hr == S_OK, "ret %08x\n", hr );
6833
6834                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6835                 ok(hr == S_OK, "ret %08x\n", hr );
6836
6837                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6838                 ok(hr == S_OK, "ret %08x\n", hr );
6839
6840                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6841                 ok(hr == S_OK, "ret %08x\n", hr );
6842                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6843                 SysFreeString(str);
6844
6845                 /* test insertData */
6846                 str = SysAllocStringLen(NULL, 0);
6847                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6848                 ok(hr == S_OK, "ret %08x\n", hr );
6849
6850                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6851                 ok(hr == S_OK, "ret %08x\n", hr );
6852
6853                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6854                 ok(hr == S_OK, "ret %08x\n", hr );
6855
6856                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6857                 ok(hr == S_OK, "ret %08x\n", hr );
6858
6859                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6860                 ok(hr == S_OK, "ret %08x\n", hr );
6861
6862                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6863                 ok(hr == S_OK, "ret %08x\n", hr );
6864                 SysFreeString(str);
6865
6866                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6867                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6868
6869                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6870                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6871
6872                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6873                 ok(hr == S_OK, "ret %08x\n", hr );
6874
6875                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6876                 ok(hr == S_OK, "ret %08x\n", hr );
6877
6878                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6879                 ok(hr == S_OK, "ret %08x\n", hr );
6880
6881                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6882                 ok(hr == S_OK, "ret %08x\n", hr );
6883                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6884                 SysFreeString(str);
6885
6886                 /* delete data */
6887                 /* invalid arguments */
6888                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6889                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6890
6891                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6892                 ok(hr == S_OK, "ret %08x\n", hr );
6893
6894                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6895                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6896
6897                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6898                 ok(hr == S_OK, "ret %08x\n", hr );
6899                 ok(len == 43, "expected 43 got %d\n", len);
6900
6901                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6902                 ok(hr == S_OK, "ret %08x\n", hr );
6903
6904                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6905                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6906
6907                 /* delete from start */
6908                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6909                 ok(hr == S_OK, "ret %08x\n", hr );
6910
6911                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6912                 ok(hr == S_OK, "ret %08x\n", hr );
6913                 ok(len == 38, "expected 38 got %d\n", len);
6914
6915                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6916                 ok(hr == S_OK, "ret %08x\n", hr );
6917                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6918                 SysFreeString(str);
6919
6920                 /* delete from end */
6921                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6922                 ok(hr == S_OK, "ret %08x\n", hr );
6923
6924                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6925                 ok(hr == S_OK, "ret %08x\n", hr );
6926                 ok(len == 35, "expected 35 got %d\n", len);
6927
6928                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6929                 ok(hr == S_OK, "ret %08x\n", hr );
6930                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6931                 SysFreeString(str);
6932
6933                 /* delete from inside */
6934                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6935                 ok(hr == S_OK, "ret %08x\n", hr );
6936
6937                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6938                 ok(hr == S_OK, "ret %08x\n", hr );
6939                 ok(len == 2, "expected 2 got %d\n", len);
6940
6941                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6942                 ok(hr == S_OK, "ret %08x\n", hr );
6943                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6944                 SysFreeString(str);
6945
6946                 /* delete whole data ... */
6947                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6948                 ok(hr == S_OK, "ret %08x\n", hr );
6949
6950                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6951                 ok(hr == S_OK, "ret %08x\n", hr );
6952
6953                 /* ... and try again with empty string */
6954                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6955                 ok(hr == S_OK, "ret %08x\n", hr );
6956
6957                 /* ::replaceData() */
6958                 V_VT(&v) = VT_BSTR;
6959                 V_BSTR(&v) = SysAllocString(szstr1);
6960                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6961                 ok(hr == S_OK, "ret %08x\n", hr );
6962                 VariantClear(&v);
6963
6964                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6965                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6966                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6967                 ok(hr == S_OK, "ret %08x\n", hr );
6968                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6969                 SysFreeString(str);
6970
6971                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6972                 ok(hr == S_OK, "ret %08x\n", hr );
6973                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6974                 ok(hr == S_OK, "ret %08x\n", hr );
6975                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6976                 SysFreeString(str);
6977
6978                 /* NULL pointer means delete */
6979                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6980                 ok(hr == S_OK, "ret %08x\n", hr );
6981                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6982                 ok(hr == S_OK, "ret %08x\n", hr );
6983                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6984                 SysFreeString(str);
6985
6986                 /* empty string means delete */
6987                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6988                 ok(hr == S_OK, "ret %08x\n", hr );
6989                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6990                 ok(hr == S_OK, "ret %08x\n", hr );
6991                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6992                 SysFreeString(str);
6993
6994                 /* zero count means insert */
6995                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6996                 ok(hr == S_OK, "ret %08x\n", hr );
6997                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6998                 ok(hr == S_OK, "ret %08x\n", hr );
6999                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
7000                 SysFreeString(str);
7001
7002                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
7003                 ok(hr == S_OK, "ret %08x\n", hr );
7004
7005                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
7006                 ok(hr == S_OK, "ret %08x\n", hr );
7007                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
7008                 ok(hr == S_OK, "ret %08x\n", hr );
7009                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
7010                 SysFreeString(str);
7011
7012                 /* nonempty string, count greater than its length */
7013                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
7014                 ok(hr == S_OK, "ret %08x\n", hr );
7015                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
7016                 ok(hr == S_OK, "ret %08x\n", hr );
7017                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
7018                 SysFreeString(str);
7019
7020                 /* nonempty string, count less than its length */
7021                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
7022                 ok(hr == S_OK, "ret %08x\n", hr );
7023                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
7024                 ok(hr == S_OK, "ret %08x\n", hr );
7025                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
7026                 SysFreeString(str);
7027
7028                 IXMLDOMCDATASection_Release(pCDataSec);
7029             }
7030
7031             /* Document Fragments */
7032             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
7033             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7034
7035             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
7036             ok(hr == S_OK, "ret %08x\n", hr );
7037             if(hr == S_OK)
7038             {
7039                 IXMLDOMNode *node;
7040
7041                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
7042                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7043
7044                 node = (IXMLDOMNode *)0x1;
7045                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
7046                 ok(hr == S_FALSE, "ret %08x\n", hr );
7047                 ok(node == NULL, "expected NULL, got %p\n", node);
7048
7049                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
7050                 ok(hr == S_OK, "ret %08x\n", hr );
7051
7052                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
7053                 ok(hr == S_OK, "ret %08x\n", hr );
7054                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
7055                 SysFreeString(str);
7056
7057                 /* test next Sibling*/
7058                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
7059                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7060
7061                 node = (IXMLDOMNode *)0x1;
7062                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
7063                 ok(hr == S_FALSE, "ret %08x\n", hr );
7064                 ok(node == NULL, "next sibling not NULL\n");
7065
7066                 /* test Previous Sibling*/
7067                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
7068                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7069
7070                 node = (IXMLDOMNode *)0x1;
7071                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
7072                 ok(hr == S_FALSE, "ret %08x\n", hr );
7073                 ok(node == NULL, "previous sibling not NULL\n");
7074
7075                 IXMLDOMDocumentFragment_Release(pDocFrag);
7076             }
7077
7078             /* Entity References */
7079             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
7080             ok(hr == E_FAIL, "ret %08x\n", hr );
7081             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
7082             ok(hr == E_FAIL, "ret %08x\n", hr );
7083
7084             str = SysAllocString(szEntityRef);
7085             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
7086             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7087
7088             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
7089             SysFreeString(str);
7090             ok(hr == S_OK, "ret %08x\n", hr );
7091             if(hr == S_OK)
7092             {
7093                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
7094                 ok(hr == S_OK, "ret %08x\n", hr );
7095
7096                 /* test get_xml*/
7097                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
7098                 ok(hr == S_OK, "ret %08x\n", hr );
7099                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
7100                 SysFreeString(str);
7101
7102                 IXMLDOMEntityReference_Release(pEntityRef);
7103             }
7104
7105             IXMLDOMElement_Release( pRoot );
7106         }
7107     }
7108
7109     IXMLDOMDocument_Release(doc);
7110
7111     free_bstrs();
7112 }
7113
7114 typedef struct {
7115     const char *name;
7116     const char *type;
7117     HRESULT hr;
7118 } put_datatype_t;
7119
7120 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
7121    So many of the names have been changed to reflect this. */
7122 static put_datatype_t put_datatype_data[] = {
7123     { "test_inval",      "abcdefg",     E_FAIL },
7124     { "test_bool",       "Boolean",     S_OK },
7125     { "test_string",     "String",      S_OK },
7126     { "test_number",     "number",      S_OK },
7127     { "test_int",        "InT",         S_OK },
7128     { "test_fixed",      "fixed.14.4",  S_OK },
7129     { "test_datetime",   "DateTime",    S_OK },
7130     { "test_datetimetz", "DateTime.tz", S_OK },
7131     { "test_date",       "Date",        S_OK },
7132     { "test_time",       "Time",        S_OK },
7133     { "test_timetz",     "Time.tz",     S_OK },
7134     { "test_I1",         "I1",          S_OK },
7135     { "test_I2",         "I2",          S_OK },
7136     { "test_I4",         "I4",          S_OK },
7137     { "test_UI1",        "UI1",         S_OK },
7138     { "test_UI2",        "UI2",         S_OK },
7139     { "test_UI4",        "UI4",         S_OK },
7140     { "test_r4",         "r4",          S_OK },
7141     { "test_r8",         "r8",          S_OK },
7142     { "test_float",      "float",       S_OK },
7143     { "test_uuid",       "UuId",        S_OK },
7144     { "test_binhex",     "bin.hex",     S_OK },
7145     { "test_binbase64",  "bin.base64",  S_OK },
7146     { NULL }
7147 };
7148
7149 typedef struct {
7150     DOMNodeType type;
7151     HRESULT hr;
7152 } put_datatype_notype_t;
7153
7154 static put_datatype_notype_t put_dt_notype[] = {
7155     { NODE_PROCESSING_INSTRUCTION, E_FAIL },
7156     { NODE_DOCUMENT_FRAGMENT,      E_FAIL },
7157     { NODE_ENTITY_REFERENCE,       E_FAIL },
7158     { NODE_CDATA_SECTION,          E_FAIL },
7159     { NODE_COMMENT,                E_FAIL },
7160     { NODE_INVALID }
7161 };
7162
7163 static void test_put_dataType( void )
7164 {
7165     const put_datatype_notype_t *ptr2 = put_dt_notype;
7166     const put_datatype_t *ptr = put_datatype_data;
7167     IXMLDOMElement *root, *element;
7168     BSTR nameW, type1W, type2W;
7169     IXMLDOMDocument *doc;
7170     HRESULT hr;
7171
7172     doc = create_document(&IID_IXMLDOMDocument);
7173     if (!doc) return;
7174
7175     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
7176     EXPECT_HR(hr, E_INVALIDARG);
7177
7178     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7179     EXPECT_HR(hr, S_OK);
7180
7181     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7182     EXPECT_HR(hr, S_OK);
7183
7184     hr = IXMLDOMElement_put_dataType(root, NULL);
7185     EXPECT_HR(hr, E_INVALIDARG);
7186
7187     while (ptr->name)
7188     {
7189         hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
7190         EXPECT_HR(hr, S_OK);
7191         if(hr == S_OK)
7192         {
7193             hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
7194             EXPECT_HR(hr, S_OK);
7195
7196             hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
7197             ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
7198
7199             IXMLDOMElement_Release(element);
7200         }
7201         ptr++;
7202     }
7203
7204     /* check changing types */
7205     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
7206     EXPECT_HR(hr, S_OK);
7207
7208     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
7209     EXPECT_HR(hr, S_OK);
7210
7211     hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
7212     EXPECT_HR(hr, S_OK);
7213
7214     hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
7215     EXPECT_HR(hr, S_OK);
7216
7217     IXMLDOMElement_Release(element);
7218
7219     /* try to set type for node without a type */
7220     nameW  = _bstr_("testname");
7221     type1W = _bstr_("string");
7222     type2W = _bstr_("number");
7223     while (ptr2->type != NODE_INVALID)
7224     {
7225         IXMLDOMNode *node;
7226         VARIANT type;
7227
7228         V_VT(&type) = VT_I2;
7229         V_I2(&type) = ptr2->type;
7230
7231         hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
7232         EXPECT_HR(hr, S_OK);
7233         if(hr == S_OK)
7234         {
7235             hr = IXMLDOMElement_appendChild(root, node, NULL);
7236             EXPECT_HR(hr, S_OK);
7237
7238             hr = IXMLDOMNode_put_dataType(node, NULL);
7239             EXPECT_HR(hr, E_INVALIDARG);
7240
7241             hr = IXMLDOMNode_put_dataType(node, type1W);
7242             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7243             hr = IXMLDOMNode_put_dataType(node, type2W);
7244             ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
7245
7246             IXMLDOMNode_Release(node);
7247         }
7248         ptr2++;
7249     }
7250
7251     IXMLDOMElement_Release(root);
7252     IXMLDOMDocument_Release(doc);
7253     free_bstrs();
7254 }
7255
7256 static void test_save(void)
7257 {
7258     IXMLDOMDocument *doc, *doc2;
7259     IXMLDOMElement *root;
7260     BSTR sOrig, sNew, filename;
7261     char buffer[100];
7262     IStream *stream;
7263     HGLOBAL global;
7264     VARIANT_BOOL b;
7265     DWORD read = 0;
7266     VARIANT dest;
7267     HANDLE hfile;
7268     HRESULT hr;
7269     char *ptr;
7270
7271     doc = create_document(&IID_IXMLDOMDocument);
7272     if (!doc) return;
7273
7274     doc2 = create_document(&IID_IXMLDOMDocument);
7275     if (!doc2)
7276     {
7277         IXMLDOMDocument_Release(doc);
7278         return;
7279     }
7280
7281     /* save to IXMLDOMDocument */
7282     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
7283     EXPECT_HR(hr, S_OK);
7284
7285     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
7286     EXPECT_HR(hr, S_OK);
7287
7288     V_VT(&dest) = VT_UNKNOWN;
7289     V_UNKNOWN(&dest) = (IUnknown*)doc2;
7290
7291     hr = IXMLDOMDocument_save(doc, dest);
7292     EXPECT_HR(hr, S_OK);
7293
7294     hr = IXMLDOMDocument_get_xml(doc, &sOrig);
7295     EXPECT_HR(hr, S_OK);
7296
7297     hr = IXMLDOMDocument_get_xml(doc2, &sNew);
7298     EXPECT_HR(hr, S_OK);
7299
7300     ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
7301
7302     SysFreeString(sOrig);
7303     SysFreeString(sNew);
7304
7305     IXMLDOMElement_Release(root);
7306     IXMLDOMDocument_Release(doc2);
7307
7308     /* save to path */
7309     V_VT(&dest) = VT_BSTR;
7310     V_BSTR(&dest) = _bstr_("test.xml");
7311
7312     hr = IXMLDOMDocument_save(doc, dest);
7313     EXPECT_HR(hr, S_OK);
7314
7315     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7316     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7317     if(hfile == INVALID_HANDLE_VALUE) return;
7318
7319     ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7320     ok(read != 0, "could not read file\n");
7321     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7322
7323     CloseHandle(hfile);
7324     DeleteFile("test.xml");
7325
7326     /* save to path VT_BSTR | VT_BYREF */
7327     filename = _bstr_("test.xml");
7328     V_VT(&dest) = VT_BSTR | VT_BYREF;
7329     V_BSTRREF(&dest) = &filename;
7330
7331     hr = IXMLDOMDocument_save(doc, dest);
7332     EXPECT_HR(hr, S_OK);
7333
7334     hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
7335     ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
7336     if(hfile == INVALID_HANDLE_VALUE) return;
7337
7338     if (hfile != INVALID_HANDLE_VALUE)
7339     {
7340        ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
7341        ok(read != 0, "could not read file\n");
7342        ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
7343
7344        CloseHandle(hfile);
7345        DeleteFile("test.xml");
7346     }
7347
7348     /* save to stream */
7349     V_VT(&dest) = VT_UNKNOWN;
7350     V_UNKNOWN(&dest) = (IUnknown*)&savestream;
7351
7352     hr = IXMLDOMDocument_save(doc, dest);
7353     EXPECT_HR(hr, S_OK);
7354
7355     /* loaded data contains xml declaration */
7356     hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b);
7357     EXPECT_HR(hr, S_OK);
7358
7359     CreateStreamOnHGlobal(NULL, TRUE, &stream);
7360     V_VT(&dest) = VT_UNKNOWN;
7361     V_UNKNOWN(&dest) = (IUnknown*)stream;
7362     hr = IXMLDOMDocument_save(doc, dest);
7363     EXPECT_HR(hr, S_OK);
7364
7365     hr = GetHGlobalFromStream(stream, &global);
7366     EXPECT_HR(hr, S_OK);
7367     ptr = GlobalLock(global);
7368     ok(!memcmp(ptr, win1252decl, strlen(win1252decl)), "got wrong xml declaration\n");
7369     GlobalUnlock(global);
7370     IStream_Release(stream);
7371
7372     /* loaded data without xml declaration */
7373     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b);
7374     EXPECT_HR(hr, S_OK);
7375
7376     CreateStreamOnHGlobal(NULL, TRUE, &stream);
7377     V_VT(&dest) = VT_UNKNOWN;
7378     V_UNKNOWN(&dest) = (IUnknown*)stream;
7379     hr = IXMLDOMDocument_save(doc, dest);
7380     EXPECT_HR(hr, S_OK);
7381
7382     hr = GetHGlobalFromStream(stream, &global);
7383     EXPECT_HR(hr, S_OK);
7384     ptr = GlobalLock(global);
7385     ok(ptr[0] == '<' && ptr[1] != '?', "got wrong start tag %c%c\n", ptr[0], ptr[1]);
7386     GlobalUnlock(global);
7387     IStream_Release(stream);
7388
7389     IXMLDOMDocument_Release(doc);
7390     free_bstrs();
7391 }
7392
7393 static void test_testTransforms(void)
7394 {
7395     IXMLDOMDocument *doc, *docSS;
7396     IXMLDOMNode *pNode;
7397     VARIANT_BOOL bSucc;
7398
7399     HRESULT hr;
7400
7401     doc = create_document(&IID_IXMLDOMDocument);
7402     if (!doc) return;
7403
7404     docSS = create_document(&IID_IXMLDOMDocument);
7405     if (!docSS)
7406     {
7407         IXMLDOMDocument_Release(doc);
7408         return;
7409     }
7410
7411     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
7412     ok(hr == S_OK, "ret %08x\n", hr );
7413
7414     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
7415     ok(hr == S_OK, "ret %08x\n", hr );
7416
7417     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
7418     ok(hr == S_OK, "ret %08x\n", hr );
7419     if(hr == S_OK)
7420     {
7421         BSTR bOut;
7422
7423         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
7424         ok(hr == S_OK, "ret %08x\n", hr );
7425         if(hr == S_OK)
7426         {
7427             ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
7428             SysFreeString(bOut);
7429         }
7430
7431         IXMLDOMNode_Release(pNode);
7432     }
7433
7434     IXMLDOMDocument_Release(docSS);
7435     IXMLDOMDocument_Release(doc);
7436
7437     free_bstrs();
7438 }
7439
7440 struct namespaces_change_t {
7441     const CLSID *clsid;
7442     const char *name;
7443 };
7444
7445 static const struct namespaces_change_t namespaces_change_test_data[] = {
7446     { &CLSID_DOMDocument,   "CLSID_DOMDocument"   },
7447     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2"  },
7448     { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
7449     { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
7450     { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
7451     { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
7452     { 0 }
7453 };
7454
7455 static void test_namespaces_change(void)
7456 {
7457     const struct namespaces_change_t *class_ptr = namespaces_change_test_data;
7458
7459     while (class_ptr->clsid)
7460     {
7461         IXMLDOMDocument *doc = NULL;
7462         IXMLDOMElement *elem = NULL;
7463         IXMLDOMNode *node = NULL;
7464
7465         VARIANT var;
7466         HRESULT hr;
7467         BSTR str;
7468
7469         hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
7470                               &IID_IXMLDOMDocument, (void**)&doc);
7471         if (hr != S_OK)
7472         {
7473             win_skip("failed to create class instance for %s\n", class_ptr->name);
7474             class_ptr++;
7475             continue;
7476         }
7477
7478         V_VT(&var) = VT_I2;
7479         V_I2(&var) = NODE_ELEMENT;
7480
7481         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
7482         EXPECT_HR(hr, S_OK);
7483
7484         hr = IXMLDOMDocument_appendChild(doc, node, NULL);
7485         EXPECT_HR(hr, S_OK);
7486
7487         hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7488         EXPECT_HR(hr, S_OK);
7489
7490         /* try same prefix, different uri */
7491         V_VT(&var) = VT_BSTR;
7492         V_BSTR(&var) = _bstr_("ns/uri2");
7493
7494         hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7495         EXPECT_HR(hr, E_INVALIDARG);
7496
7497         /* try same prefix and uri */
7498         V_VT(&var) = VT_BSTR;
7499         V_BSTR(&var) = _bstr_("ns/uri");
7500
7501         hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
7502         EXPECT_HR(hr, S_OK);
7503
7504         hr = IXMLDOMElement_get_xml(elem, &str);
7505         EXPECT_HR(hr, S_OK);
7506         ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s for %s\n",
7507            wine_dbgstr_w(str), class_ptr->name);
7508         SysFreeString(str);
7509
7510         IXMLDOMElement_Release(elem);
7511         IXMLDOMDocument_Release(doc);
7512
7513         free_bstrs();
7514
7515         class_ptr++;
7516     }
7517 }
7518
7519 static void test_namespaces_basic(void)
7520 {
7521     static const CHAR namespaces_xmlA[] =
7522         "<?xml version=\"1.0\"?>\n"
7523         "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
7524         "  <XMI.content>"
7525         "    <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
7526         "  </XMI.content>"
7527         "</XMI>";
7528
7529     IXMLDOMDocument *doc;
7530     IXMLDOMElement *elem;
7531     IXMLDOMNode *node;
7532
7533     VARIANT_BOOL b;
7534     HRESULT hr;
7535     BSTR str;
7536
7537     doc = create_document(&IID_IXMLDOMDocument);
7538     if (!doc) return;
7539
7540     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
7541     EXPECT_HR(hr, S_OK);
7542     ok(b == VARIANT_TRUE, "got %d\n", b);
7543
7544     str = (BSTR)0xdeadbeef;
7545     hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
7546     EXPECT_HR(hr, S_FALSE);
7547     ok(str == NULL, "got %p\n", str);
7548
7549     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
7550     EXPECT_HR(hr, S_OK);
7551     if(hr == S_OK)
7552     {
7553         IXMLDOMAttribute *attr;
7554         IXMLDOMNode *node2;
7555
7556         hr = IXMLDOMNode_get_firstChild(node, &node2);
7557         EXPECT_HR(hr, S_OK);
7558         ok(node2 != NULL, "got %p\n", node2);
7559
7560         /* Test get_prefix */
7561         hr = IXMLDOMNode_get_prefix(node2, NULL);
7562         EXPECT_HR(hr, E_INVALIDARG);
7563         /* NOTE: Need to test that arg2 gets cleared on Error. */
7564
7565         hr = IXMLDOMNode_get_prefix(node2, &str);
7566         EXPECT_HR(hr, S_OK);
7567         ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7568         SysFreeString(str);
7569
7570         hr = IXMLDOMNode_get_nodeName(node2, &str);
7571         EXPECT_HR(hr, S_OK);
7572         ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
7573         SysFreeString(str);
7574
7575         /* Test get_namespaceURI */
7576         hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
7577         EXPECT_HR(hr, E_INVALIDARG);
7578         /* NOTE: Need to test that arg2 gets cleared on Error. */
7579
7580         hr = IXMLDOMNode_get_namespaceURI(node2, &str);
7581         EXPECT_HR(hr, S_OK);
7582         ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
7583         SysFreeString(str);
7584
7585         hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
7586         EXPECT_HR(hr, S_OK);
7587
7588         hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
7589         EXPECT_HR(hr, S_OK);
7590
7591         hr = IXMLDOMAttribute_get_nodeName(attr, &str);
7592         EXPECT_HR(hr, S_OK);
7593         ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
7594         SysFreeString(str);
7595
7596         hr = IXMLDOMAttribute_get_prefix(attr, &str);
7597         EXPECT_HR(hr, S_OK);
7598         ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
7599         SysFreeString(str);
7600
7601         IXMLDOMAttribute_Release(attr);
7602         IXMLDOMElement_Release(elem);
7603
7604         IXMLDOMNode_Release(node2);
7605         IXMLDOMNode_Release(node);
7606     }
7607
7608     IXMLDOMDocument_Release(doc);
7609
7610     free_bstrs();
7611 }
7612
7613 static void test_FormattingXML(void)
7614 {
7615     IXMLDOMDocument *doc;
7616     IXMLDOMElement *pElement;
7617     VARIANT_BOOL bSucc;
7618     HRESULT hr;
7619     BSTR str;
7620     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
7621     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
7622
7623     doc = create_document(&IID_IXMLDOMDocument);
7624     if (!doc) return;
7625
7626     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
7627     ok(hr == S_OK, "ret %08x\n", hr );
7628     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7629
7630     if(bSucc == VARIANT_TRUE)
7631     {
7632         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
7633         ok(hr == S_OK, "ret %08x\n", hr );
7634         if(hr == S_OK)
7635         {
7636             hr = IXMLDOMElement_get_xml(pElement, &str);
7637             ok(hr == S_OK, "ret %08x\n", hr );
7638             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
7639             SysFreeString(str);
7640
7641             IXMLDOMElement_Release(pElement);
7642         }
7643     }
7644
7645     IXMLDOMDocument_Release(doc);
7646
7647     free_bstrs();
7648 }
7649
7650 typedef struct _nodetypedvalue_t {
7651     const char *name;
7652     VARTYPE type;
7653     const char *value; /* value in string format */
7654 } nodetypedvalue_t;
7655
7656 static const nodetypedvalue_t get_nodetypedvalue[] = {
7657     { "root/string",    VT_BSTR, "Wine" },
7658     { "root/string2",   VT_BSTR, "String" },
7659     { "root/number",    VT_BSTR, "12.44" },
7660     { "root/number2",   VT_BSTR, "-3.71e3" },
7661     { "root/int",       VT_I4,   "-13" },
7662     { "root/fixed",     VT_CY,   "7322.9371" },
7663     { "root/bool",      VT_BOOL, "-1" },
7664     { "root/datetime",  VT_DATE, "40135.14" },
7665     { "root/datetimetz",VT_DATE, "37813.59" },
7666     { "root/date",      VT_DATE, "665413" },
7667     { "root/time",      VT_DATE, "0.5813889" },
7668     { "root/timetz",    VT_DATE, "1.112512" },
7669     { "root/i1",        VT_I1,   "-13" },
7670     { "root/i2",        VT_I2,   "31915" },
7671     { "root/i4",        VT_I4,   "-312232" },
7672     { "root/ui1",       VT_UI1,  "123" },
7673     { "root/ui2",       VT_UI2,  "48282" },
7674     { "root/ui4",       VT_UI4,  "949281" },
7675     { "root/r4",        VT_R4,   "213124" },
7676     { "root/r8",        VT_R8,   "0.412" },
7677     { "root/float",     VT_R8,   "41221.421" },
7678     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7679     { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7680     { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7681     { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7682     { 0 }
7683 };
7684
7685 static void test_nodeTypedValue(void)
7686 {
7687     const nodetypedvalue_t *entry = get_nodetypedvalue;
7688     IXMLDOMDocumentType *doctype, *doctype2;
7689     IXMLDOMProcessingInstruction *pi;
7690     IXMLDOMDocumentFragment *frag;
7691     IXMLDOMDocument *doc, *doc2;
7692     IXMLDOMCDATASection *cdata;
7693     IXMLDOMComment *comment;
7694     IXMLDOMNode *node;
7695     VARIANT_BOOL b;
7696     VARIANT value;
7697     HRESULT hr;
7698
7699     doc = create_document(&IID_IXMLDOMDocument);
7700     if (!doc) return;
7701
7702     b = VARIANT_FALSE;
7703     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7704     ok(hr == S_OK, "ret %08x\n", hr );
7705     ok(b == VARIANT_TRUE, "got %d\n", b);
7706
7707     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7708     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7709
7710     V_VT(&value) = VT_BSTR;
7711     V_BSTR(&value) = NULL;
7712     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7713     ok(hr == S_FALSE, "ret %08x\n", hr );
7714     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7715
7716     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7717     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7718
7719     V_VT(&value) = VT_EMPTY;
7720     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7721     ok(hr == S_FALSE, "ret %08x\n", hr );
7722     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7723
7724     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7725     ok(hr == S_OK, "ret %08x\n", hr );
7726
7727     V_VT(&value) = VT_BSTR;
7728     V_BSTR(&value) = NULL;
7729     hr = IXMLDOMNode_get_nodeValue(node, &value);
7730     ok(hr == S_FALSE, "ret %08x\n", hr );
7731     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7732
7733     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7734     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
7735
7736     IXMLDOMNode_Release(node);
7737
7738     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7739     ok(hr == S_OK, "ret %08x\n", hr );
7740     {
7741         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7742
7743         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7744         ok(hr == S_OK, "ret %08x\n", hr );
7745         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7746         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7747         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7748             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7749         VariantClear(&value);
7750         IXMLDOMNode_Release(node);
7751     }
7752
7753     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7754     ok(hr == S_OK, "ret %08x\n", hr );
7755     {
7756         V_VT(&value) = VT_NULL;
7757         V_BSTR(&value) = (void*)0xdeadbeef;
7758         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7759         ok(hr == S_OK, "ret %08x\n", hr );
7760         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7761         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
7762         IXMLDOMProcessingInstruction_Release(pi);
7763         VariantClear(&value);
7764     }
7765
7766     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7767     ok(hr == S_OK, "ret %08x\n", hr );
7768     {
7769         V_VT(&value) = VT_NULL;
7770         V_BSTR(&value) = (void*)0xdeadbeef;
7771         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7772         ok(hr == S_OK, "ret %08x\n", hr );
7773         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7774         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
7775         IXMLDOMCDATASection_Release(cdata);
7776         VariantClear(&value);
7777     }
7778
7779     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7780     ok(hr == S_OK, "ret %08x\n", hr );
7781     {
7782         V_VT(&value) = VT_NULL;
7783         V_BSTR(&value) = (void*)0xdeadbeef;
7784         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7785         ok(hr == S_OK, "ret %08x\n", hr );
7786         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7787         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
7788         IXMLDOMComment_Release(comment);
7789         VariantClear(&value);
7790     }
7791
7792     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7793     ok(hr == S_OK, "ret %08x\n", hr );
7794     {
7795         V_VT(&value) = VT_EMPTY;
7796         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7797         ok(hr == S_FALSE, "ret %08x\n", hr );
7798         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7799         IXMLDOMDocumentFragment_Release(frag);
7800     }
7801
7802     doc2 = create_document(&IID_IXMLDOMDocument);
7803
7804     b = VARIANT_FALSE;
7805     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7806     ok(hr == S_OK, "ret %08x\n", hr );
7807     ok(b == VARIANT_TRUE, "got %d\n", b);
7808
7809     EXPECT_REF(doc2, 1);
7810
7811     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7812     ok(hr == S_OK, "ret %08x\n", hr );
7813
7814     EXPECT_REF(doc2, 1);
7815     todo_wine EXPECT_REF(doctype, 2);
7816
7817     {
7818         V_VT(&value) = VT_EMPTY;
7819         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7820         ok(hr == S_FALSE, "ret %08x\n", hr );
7821         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7822     }
7823
7824     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7825     ok(hr == S_OK, "ret %08x\n", hr );
7826     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7827
7828     IXMLDOMDocumentType_Release(doctype2);
7829     IXMLDOMDocumentType_Release(doctype);
7830
7831     IXMLDOMDocument_Release(doc2);
7832
7833     while (entry->name)
7834     {
7835         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7836         ok(hr == S_OK, "ret %08x\n", hr );
7837
7838         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7839         ok(hr == S_OK, "ret %08x\n", hr );
7840         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7841
7842         if (entry->type == (VT_ARRAY|VT_UI1))
7843         {
7844             ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7845                "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
7846         }
7847
7848         if (entry->type != VT_BSTR)
7849         {
7850            if (entry->type == VT_DATE ||
7851                entry->type == VT_R8 ||
7852                entry->type == VT_CY)
7853            {
7854                if (entry->type == VT_DATE)
7855                {
7856                    hr = VariantChangeType(&value, &value, 0, VT_R4);
7857                    ok(hr == S_OK, "ret %08x\n", hr );
7858                }
7859                hr = VariantChangeTypeEx(&value, &value,
7860                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7861                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
7862                ok(hr == S_OK, "ret %08x\n", hr );
7863            }
7864            else
7865            {
7866                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7867                ok(hr == S_OK, "ret %08x\n", hr );
7868            }
7869
7870            /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7871            if (entry->type == (VT_ARRAY|VT_UI1))
7872            {
7873                ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7874                   "expected %s\n", entry->value);
7875            }
7876            else
7877                ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7878                   "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7879         }
7880         else
7881            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7882                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7883
7884         VariantClear( &value );
7885         IXMLDOMNode_Release(node);
7886
7887         entry++;
7888     }
7889
7890     IXMLDOMDocument_Release(doc);
7891     free_bstrs();
7892 }
7893
7894 static void test_TransformWithLoadingLocalFile(void)
7895 {
7896     IXMLDOMDocument *doc;
7897     IXMLDOMDocument *xsl;
7898     IXMLDOMNode *pNode;
7899     VARIANT_BOOL bSucc;
7900     HRESULT hr;
7901     HANDLE file;
7902     DWORD dwWritten;
7903     char lpPathBuffer[MAX_PATH];
7904     int i;
7905
7906     /* Create a Temp File. */
7907     GetTempPathA(MAX_PATH, lpPathBuffer);
7908     strcat(lpPathBuffer, "customers.xml" );
7909
7910     file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7911     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7912     if(file == INVALID_HANDLE_VALUE)
7913         return;
7914
7915     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7916     CloseHandle(file);
7917
7918     /* Correct path to not include a escape character. */
7919     for(i=0; i < strlen(lpPathBuffer); i++)
7920     {
7921         if(lpPathBuffer[i] == '\\')
7922             lpPathBuffer[i] = '/';
7923     }
7924
7925     doc = create_document(&IID_IXMLDOMDocument);
7926     if (!doc) return;
7927
7928     xsl = create_document(&IID_IXMLDOMDocument);
7929     if (!xsl)
7930     {
7931         IXMLDOMDocument_Release(doc);
7932         return;
7933     }
7934
7935     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7936     ok(hr == S_OK, "ret %08x\n", hr );
7937     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7938     if(bSucc == VARIANT_TRUE)
7939     {
7940         BSTR sXSL;
7941         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7942         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7943         BSTR sFileName = _bstr_(lpPathBuffer);
7944         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7945
7946         sXSL = SysAllocStringLen(NULL, nLegnth);
7947         lstrcpyW(sXSL, sPart1);
7948         lstrcatW(sXSL, sFileName);
7949         lstrcatW(sXSL, sPart2);
7950
7951         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7952         ok(hr == S_OK, "ret %08x\n", hr );
7953         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7954         if(bSucc == VARIANT_TRUE)
7955         {
7956             BSTR sResult;
7957
7958             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7959             ok(hr == S_OK, "ret %08x\n", hr );
7960             if(hr == S_OK)
7961             {
7962                 /* This will load the temp file via the XSL */
7963                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7964                 ok(hr == S_OK, "ret %08x\n", hr );
7965                 if(hr == S_OK)
7966                 {
7967                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7968                     SysFreeString(sResult);
7969                 }
7970
7971                 IXMLDOMNode_Release(pNode);
7972             }
7973         }
7974
7975         SysFreeString(sXSL);
7976     }
7977
7978     IXMLDOMDocument_Release(doc);
7979     IXMLDOMDocument_Release(xsl);
7980
7981     DeleteFile(lpPathBuffer);
7982     free_bstrs();
7983 }
7984
7985 static void test_put_nodeValue(void)
7986 {
7987     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7988     IXMLDOMDocument *doc;
7989     IXMLDOMText *text;
7990     IXMLDOMEntityReference *entityref;
7991     IXMLDOMAttribute *attr;
7992     IXMLDOMNode *node;
7993     HRESULT hr;
7994     VARIANT data, type;
7995
7996     doc = create_document(&IID_IXMLDOMDocument);
7997     if (!doc) return;
7998
7999     /* test for unsupported types */
8000     /* NODE_DOCUMENT */
8001     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
8002     ok(hr == S_OK, "ret %08x\n", hr );
8003     V_VT(&data) = VT_BSTR;
8004     V_BSTR(&data) = _bstr_("one two three");
8005     hr = IXMLDOMNode_put_nodeValue(node, data);
8006     ok(hr == E_FAIL, "ret %08x\n", hr );
8007     IXMLDOMNode_Release(node);
8008
8009     /* NODE_DOCUMENT_FRAGMENT */
8010     V_VT(&type) = VT_I1;
8011     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
8012     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
8013     ok(hr == S_OK, "ret %08x\n", hr );
8014     V_VT(&data) = VT_BSTR;
8015     V_BSTR(&data) = _bstr_("one two three");
8016     hr = IXMLDOMNode_put_nodeValue(node, data);
8017     ok(hr == E_FAIL, "ret %08x\n", hr );
8018     IXMLDOMNode_Release(node);
8019
8020     /* NODE_ELEMENT */
8021     V_VT(&type) = VT_I1;
8022     V_I1(&type) = NODE_ELEMENT;
8023     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
8024     ok(hr == S_OK, "ret %08x\n", hr );
8025     V_VT(&data) = VT_BSTR;
8026     V_BSTR(&data) = _bstr_("one two three");
8027     hr = IXMLDOMNode_put_nodeValue(node, data);
8028     ok(hr == E_FAIL, "ret %08x\n", hr );
8029     IXMLDOMNode_Release(node);
8030
8031     /* NODE_ENTITY_REFERENCE */
8032     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
8033     ok(hr == S_OK, "ret %08x\n", hr );
8034
8035     V_VT(&data) = VT_BSTR;
8036     V_BSTR(&data) = _bstr_("one two three");
8037     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
8038     ok(hr == E_FAIL, "ret %08x\n", hr );
8039
8040     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
8041     ok(hr == S_OK, "ret %08x\n", hr );
8042     V_VT(&data) = VT_BSTR;
8043     V_BSTR(&data) = _bstr_("one two three");
8044     hr = IXMLDOMNode_put_nodeValue(node, data);
8045     ok(hr == E_FAIL, "ret %08x\n", hr );
8046     IXMLDOMNode_Release(node);
8047     IXMLDOMEntityReference_Release(entityref);
8048
8049     /* supported types */
8050     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
8051     ok(hr == S_OK, "ret %08x\n", hr );
8052     V_VT(&data) = VT_BSTR;
8053     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
8054     hr = IXMLDOMText_put_nodeValue(text, data);
8055     ok(hr == S_OK, "ret %08x\n", hr );
8056     IXMLDOMText_Release(text);
8057
8058     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8059     ok(hr == S_OK, "ret %08x\n", hr );
8060     V_VT(&data) = VT_BSTR;
8061     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
8062     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
8063     ok(hr == S_OK, "ret %08x\n", hr );
8064     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
8065     ok(hr == S_OK, "ret %08x\n", hr );
8066     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
8067         wine_dbgstr_w(V_BSTR(&data)));
8068     VariantClear(&data);
8069     IXMLDOMAttribute_Release(attr);
8070
8071     free_bstrs();
8072
8073     IXMLDOMDocument_Release(doc);
8074 }
8075
8076 static void test_document_IObjectSafety(void)
8077 {
8078     IXMLDOMDocument *doc;
8079     IObjectSafety *safety;
8080     HRESULT hr;
8081
8082     doc = create_document(&IID_IXMLDOMDocument);
8083     if (!doc) return;
8084
8085     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
8086     ok(hr == S_OK, "ret %08x\n", hr );
8087
8088     test_IObjectSafety_common(safety);
8089
8090     IObjectSafety_Release(safety);
8091
8092     IXMLDOMDocument_Release(doc);
8093 }
8094
8095 typedef struct _property_test_t {
8096     const GUID *guid;
8097     const char *clsid;
8098     const char *property;
8099     const char *value;
8100 } property_test_t;
8101
8102 static const property_test_t properties_test_data[] = {
8103     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
8104     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
8105     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
8106     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
8107     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
8108     { 0 }
8109 };
8110
8111 static void test_default_properties(void)
8112 {
8113     const property_test_t *entry = properties_test_data;
8114
8115     while (entry->guid)
8116     {
8117         IXMLDOMDocument2 *doc;
8118         VARIANT var;
8119         HRESULT hr;
8120
8121         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
8122         if (hr != S_OK)
8123         {
8124             win_skip("can't create %s instance\n", entry->clsid);
8125             entry++;
8126             continue;
8127         }
8128
8129         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
8130         ok(hr == S_OK, "got 0x%08x\n", hr);
8131         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
8132            entry->value, entry->clsid);
8133         VariantClear(&var);
8134
8135         IXMLDOMDocument2_Release(doc);
8136
8137         entry++;
8138     }
8139 }
8140
8141 typedef struct {
8142     const char *query;
8143     const char *list;
8144 } xslpattern_test_t;
8145
8146 static const xslpattern_test_t xslpattern_test[] = {
8147     { "root//elem[0]", "E1.E2.D1" },
8148     { "root//elem[index()=1]", "E2.E2.D1" },
8149     { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
8150     { "root//elem[end()]", "E4.E2.D1" },
8151     { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
8152     { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
8153     { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
8154     { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
8155     { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
8156     { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
8157     { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
8158     { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
8159     { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
8160     { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
8161     { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
8162     { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
8163     { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
8164     { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
8165     { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
8166     { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
8167     { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
8168     { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
8169     { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
8170     { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
8171     { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
8172     { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
8173     { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8174     { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8175     { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8176     { "root/elem[0]", "E1.E2.D1" },
8177     { "root/elem[index()=1]", "E2.E2.D1" },
8178     { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
8179     { "root/elem[end()]", "E4.E2.D1" },
8180     { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
8181     { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
8182     { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
8183     { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
8184     { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
8185     { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
8186     { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
8187     { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
8188     { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
8189     { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
8190     { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
8191     { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
8192     { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
8193     { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
8194     { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
8195     { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
8196     { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
8197     { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
8198     { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
8199     { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
8200     { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
8201     { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
8202     { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8203     { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8204     { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
8205     { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
8206     { NULL }
8207 };
8208
8209 static const xslpattern_test_t xslpattern_test_no_ns[] = {
8210     /* prefixes don't need to be registered, you may use them as they are in the doc */
8211     { "//bar:x", "E5.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
8212     /* prefixes must be explicitly specified in the name */
8213     { "//foo:elem", "" },
8214     { "//foo:c", "E3.E4.E2.D1" },
8215     { NULL }
8216 };
8217
8218 static const xslpattern_test_t xslpattern_test_func[] = {
8219     { "attribute()", "" },
8220     { "attribute('depth')", "" },
8221     { "root/attribute('depth')", "A'depth'.E3.D1" },
8222     { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
8223     { "//x//attribute(id)", NULL },
8224     { "//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" },
8225     { "comment()", "C2.D1" },
8226     { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
8227     { "element()", "E3.D1" },
8228     { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
8229     { "//element(a)", NULL },
8230     { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
8231     { "node()", "P1.D1 C2.D1 E3.D1" },
8232     { "//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" },
8233     { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
8234     { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
8235     { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
8236     { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
8237     { "pi()", "P1.D1" },
8238     { "//y/pi()", "P1.E4.E3.D1" },
8239     { "root/textnode()", "T2.E3.D1" },
8240     { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
8241     { NULL }
8242 };
8243
8244 static void test_XSLPattern(void)
8245 {
8246     const xslpattern_test_t *ptr = xslpattern_test;
8247     IXMLDOMDocument2 *doc;
8248     IXMLDOMNodeList *list;
8249     VARIANT_BOOL b;
8250     HRESULT hr;
8251     LONG len;
8252
8253     doc = create_document(&IID_IXMLDOMDocument2);
8254     if (!doc) return;
8255
8256     b = VARIANT_FALSE;
8257     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
8258     EXPECT_HR(hr, S_OK);
8259     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8260
8261     /* switch to XSLPattern */
8262     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
8263     EXPECT_HR(hr, S_OK);
8264
8265     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
8266     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
8267     EXPECT_HR(hr, S_OK);
8268
8269     len = 0;
8270     hr = IXMLDOMNodeList_get_length(list, &len);
8271     EXPECT_HR(hr, S_OK);
8272     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
8273     ok(len == 3, "expected 3 entries in list, got %d\n", len);
8274     IXMLDOMNodeList_Release(list);
8275
8276     while (ptr->query)
8277     {
8278         list = NULL;
8279         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8280         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8281         len = 0;
8282         hr = IXMLDOMNodeList_get_length(list, &len);
8283         ok(len != 0, "query=%s, empty list\n", ptr->query);
8284         if (len)
8285             expect_list_and_release(list, ptr->list);
8286
8287         ptr++;
8288     }
8289
8290     /* namespace handling */
8291     /* no registered namespaces */
8292     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
8293     EXPECT_HR(hr, S_OK);
8294
8295     ptr = xslpattern_test_no_ns;
8296     while (ptr->query)
8297     {
8298         list = NULL;
8299         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8300         ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8301
8302         if (*ptr->list)
8303         {
8304             len = 0;
8305             hr = IXMLDOMNodeList_get_length(list, &len);
8306             EXPECT_HR(hr, S_OK);
8307             ok(len != 0, "query=%s, empty list\n", ptr->query);
8308         }
8309         else
8310         {
8311             len = 1;
8312             hr = IXMLDOMNodeList_get_length(list, &len);
8313             EXPECT_HR(hr, S_OK);
8314             ok(len == 0, "query=%s, empty list\n", ptr->query);
8315         }
8316         if (len)
8317             expect_list_and_release(list, ptr->list);
8318
8319         ptr++;
8320     }
8321
8322     /* explicitly register prefix foo */
8323     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
8324
8325     /* now we get the same behavior as XPath */
8326     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8327     EXPECT_HR(hr, S_OK);
8328     len = 0;
8329     hr = IXMLDOMNodeList_get_length(list, &len);
8330     EXPECT_HR(hr, S_OK);
8331     ok(len != 0, "expected filled list\n");
8332     if (len)
8333         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
8334
8335     /* set prefix foo to some nonexistent namespace */
8336     hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
8337     EXPECT_HR(hr, S_OK);
8338
8339     /* the registered prefix takes precedence */
8340     hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
8341     EXPECT_HR(hr, S_OK);
8342     len = 0;
8343     hr = IXMLDOMNodeList_get_length(list, &len);
8344     EXPECT_HR(hr, S_OK);
8345     ok(len == 0, "expected empty list\n");
8346     IXMLDOMNodeList_Release(list);
8347
8348     IXMLDOMDocument2_Release(doc);
8349
8350     doc = create_document(&IID_IXMLDOMDocument2);
8351     if (!doc) return;
8352
8353     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
8354     EXPECT_HR(hr, S_OK);
8355     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8356
8357     ptr = xslpattern_test_func;
8358     while (ptr->query)
8359     {
8360         list = NULL;
8361         hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
8362         if (ptr->list)
8363         {
8364             ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8365             len = 0;
8366             hr = IXMLDOMNodeList_get_length(list, &len);
8367             if (*ptr->list)
8368             {
8369                 ok(len != 0, "query=%s, empty list\n", ptr->query);
8370                 if (len)
8371                     expect_list_and_release(list, ptr->list);
8372             }
8373             else
8374                 ok(len == 0, "query=%s, filled list\n", ptr->query);
8375         }
8376         else
8377             ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
8378
8379         ptr++;
8380     }
8381
8382     IXMLDOMDocument2_Release(doc);
8383     free_bstrs();
8384 }
8385
8386 static void test_splitText(void)
8387 {
8388     IXMLDOMCDATASection *cdata;
8389     IXMLDOMElement *root;
8390     IXMLDOMDocument *doc;
8391     IXMLDOMText *text, *text2;
8392     IXMLDOMNode *node;
8393     VARIANT var;
8394     VARIANT_BOOL success;
8395     LONG length;
8396     HRESULT hr;
8397
8398     doc = create_document(&IID_IXMLDOMDocument);
8399     if (!doc) return;
8400
8401     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
8402     ok(hr == S_OK, "got 0x%08x\n", hr);
8403
8404     hr = IXMLDOMDocument_get_documentElement(doc, &root);
8405     ok(hr == S_OK, "got 0x%08x\n", hr);
8406
8407     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
8408     ok(hr == S_OK, "got 0x%08x\n", hr);
8409
8410     V_VT(&var) = VT_EMPTY;
8411     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
8412     ok(hr == S_OK, "got 0x%08x\n", hr);
8413
8414     length = 0;
8415     hr = IXMLDOMCDATASection_get_length(cdata, &length);
8416     ok(hr == S_OK, "got 0x%08x\n", hr);
8417     ok(length > 0, "got %d\n", length);
8418
8419     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
8420     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8421
8422     text = (void*)0xdeadbeef;
8423     /* negative offset */
8424     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
8425     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8426     ok(text == (void*)0xdeadbeef, "got %p\n", text);
8427
8428     text = (void*)0xdeadbeef;
8429     /* offset outside data */
8430     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
8431     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8432     ok(text == 0, "got %p\n", text);
8433
8434     text = (void*)0xdeadbeef;
8435     /* offset outside data */
8436     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
8437     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8438     ok(text == 0, "got %p\n", text);
8439
8440     /* no empty node created */
8441     node = (void*)0xdeadbeef;
8442     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8443     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8444     ok(node == 0, "got %p\n", text);
8445
8446     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
8447     ok(hr == S_OK, "got 0x%08x\n", hr);
8448
8449     length = 0;
8450     hr = IXMLDOMText_get_length(text, &length);
8451     ok(hr == S_OK, "got 0x%08x\n", hr);
8452     ok(length == 7, "got %d\n", length);
8453
8454     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
8455     ok(hr == S_OK, "got 0x%08x\n", hr);
8456     IXMLDOMNode_Release(node);
8457
8458     /* split new text node */
8459     hr = IXMLDOMText_get_length(text, &length);
8460     ok(hr == S_OK, "got 0x%08x\n", hr);
8461
8462     node = (void*)0xdeadbeef;
8463     hr = IXMLDOMText_get_nextSibling(text, &node);
8464     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8465     ok(node == 0, "got %p\n", text);
8466
8467     hr = IXMLDOMText_splitText(text, 0, NULL);
8468     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8469
8470     text2 = (void*)0xdeadbeef;
8471     /* negative offset */
8472     hr = IXMLDOMText_splitText(text, -1, &text2);
8473     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8474     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
8475
8476     text2 = (void*)0xdeadbeef;
8477     /* offset outside data */
8478     hr = IXMLDOMText_splitText(text, length + 1, &text2);
8479     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8480     ok(text2 == 0, "got %p\n", text2);
8481
8482     text2 = (void*)0xdeadbeef;
8483     /* offset outside data */
8484     hr = IXMLDOMText_splitText(text, length, &text2);
8485     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8486     ok(text2 == 0, "got %p\n", text);
8487
8488     text2 = 0;
8489     hr = IXMLDOMText_splitText(text, 4, &text2);
8490     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8491     if (text2) IXMLDOMText_Release(text2);
8492
8493     node = 0;
8494     hr = IXMLDOMText_get_nextSibling(text, &node);
8495     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
8496     if (node) IXMLDOMNode_Release(node);
8497
8498     IXMLDOMText_Release(text);
8499     IXMLDOMElement_Release(root);
8500     IXMLDOMCDATASection_Release(cdata);
8501     free_bstrs();
8502 }
8503
8504 typedef struct {
8505     const char *name;
8506     const char *uri;
8507     HRESULT hr;
8508 } ns_item_t;
8509
8510 /* default_ns_doc used */
8511 static const ns_item_t qualified_item_tests[] = {
8512     { "xml:lang", NULL, S_FALSE },
8513     { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
8514     { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
8515     { "ns:b", NULL, S_FALSE },
8516     { "ns:b", "nshref", S_FALSE },
8517     { "b", "nshref", S_OK },
8518     { "d", NULL, S_OK },
8519     { NULL }
8520 };
8521
8522 static const ns_item_t named_item_tests[] = {
8523     { "xml:lang", NULL, S_OK },
8524     { "lang", NULL, S_FALSE },
8525     { "ns:b", NULL, S_OK },
8526     { "b", NULL, S_FALSE },
8527     { "d", NULL, S_OK },
8528     { NULL }
8529 };
8530
8531 static void test_getQualifiedItem(void)
8532 {
8533     IXMLDOMNode *pr_node, *node;
8534     IXMLDOMNodeList *root_list;
8535     IXMLDOMNamedNodeMap *map;
8536     IXMLDOMElement *element;
8537     const ns_item_t* ptr;
8538     IXMLDOMDocument *doc;
8539     VARIANT_BOOL b;
8540     HRESULT hr;
8541     LONG len;
8542
8543     doc = create_document(&IID_IXMLDOMDocument);
8544     if (!doc) return;
8545
8546     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8547     EXPECT_HR(hr, S_OK);
8548     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8549
8550     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8551     EXPECT_HR(hr, S_OK);
8552
8553     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8554     EXPECT_HR(hr, S_OK);
8555
8556     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8557     EXPECT_HR(hr, S_OK);
8558     IXMLDOMNodeList_Release(root_list);
8559
8560     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8561     EXPECT_HR(hr, S_OK);
8562     IXMLDOMNode_Release(pr_node);
8563
8564     len = 0;
8565     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8566     EXPECT_HR(hr, S_OK);
8567     ok( len == 3, "length %d\n", len);
8568
8569     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
8570     EXPECT_HR(hr, E_INVALIDARG);
8571
8572     node = (void*)0xdeadbeef;
8573     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
8574     EXPECT_HR(hr, E_INVALIDARG);
8575     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8576
8577     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
8578     EXPECT_HR(hr, E_INVALIDARG);
8579
8580     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8581     EXPECT_HR(hr, S_OK);
8582
8583     IXMLDOMNode_Release(node);
8584     IXMLDOMNamedNodeMap_Release(map);
8585     IXMLDOMElement_Release(element);
8586
8587     hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8588     EXPECT_HR(hr, S_OK);
8589
8590     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8591     EXPECT_HR(hr, S_OK);
8592
8593     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8594     EXPECT_HR(hr, S_OK);
8595     IXMLDOMNode_Release(node);
8596
8597     hr = IXMLDOMElement_get_attributes(element, &map);
8598     EXPECT_HR(hr, S_OK);
8599
8600     ptr = qualified_item_tests;
8601     while (ptr->name)
8602     {
8603        node = (void*)0xdeadbeef;
8604        hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8605        ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
8606        if (hr == S_OK)
8607            IXMLDOMNode_Release(node);
8608        else
8609            ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8610        ptr++;
8611     }
8612
8613     ptr = named_item_tests;
8614     while (ptr->name)
8615     {
8616        node = (void*)0xdeadbeef;
8617        hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8618        ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
8619        if (hr == S_OK)
8620            IXMLDOMNode_Release(node);
8621        else
8622            ok(node == NULL, "%s: got %p\n", ptr->name, node);
8623        ptr++;
8624     }
8625
8626     IXMLDOMNamedNodeMap_Release(map);
8627
8628     IXMLDOMElement_Release(element);
8629     IXMLDOMDocument_Release(doc);
8630     free_bstrs();
8631 }
8632
8633 static void test_removeQualifiedItem(void)
8634 {
8635     IXMLDOMDocument *doc;
8636     IXMLDOMElement *element;
8637     IXMLDOMNode *pr_node, *node;
8638     IXMLDOMNodeList *root_list;
8639     IXMLDOMNamedNodeMap *map;
8640     VARIANT_BOOL b;
8641     LONG len;
8642     HRESULT hr;
8643
8644     doc = create_document(&IID_IXMLDOMDocument);
8645     if (!doc) return;
8646
8647     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8648     ok( hr == S_OK, "loadXML failed\n");
8649     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8650
8651     hr = IXMLDOMDocument_get_documentElement(doc, &element);
8652     ok( hr == S_OK, "ret %08x\n", hr);
8653
8654     hr = IXMLDOMElement_get_childNodes(element, &root_list);
8655     ok( hr == S_OK, "ret %08x\n", hr);
8656
8657     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8658     ok( hr == S_OK, "ret %08x\n", hr);
8659     IXMLDOMNodeList_Release(root_list);
8660
8661     hr = IXMLDOMNode_get_attributes(pr_node, &map);
8662     ok( hr == S_OK, "ret %08x\n", hr);
8663     IXMLDOMNode_Release(pr_node);
8664
8665     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8666     ok( hr == S_OK, "ret %08x\n", hr);
8667     ok( len == 3, "length %d\n", len);
8668
8669     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8670     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8671
8672     node = (void*)0xdeadbeef;
8673     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8674     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
8675     ok( node == (void*)0xdeadbeef, "got %p\n", node);
8676
8677     /* out pointer is optional */
8678     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8679     ok( hr == S_OK, "ret %08x\n", hr);
8680
8681     /* already removed */
8682     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8683     ok( hr == S_FALSE, "ret %08x\n", hr);
8684
8685     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8686     ok( hr == S_OK, "ret %08x\n", hr);
8687     IXMLDOMNode_Release(node);
8688
8689     IXMLDOMNamedNodeMap_Release( map );
8690     IXMLDOMElement_Release( element );
8691     IXMLDOMDocument_Release( doc );
8692     free_bstrs();
8693 }
8694
8695 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8696 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8697 {
8698     VARIANT_BOOL b;
8699     VARIANT var;
8700     HRESULT hr;
8701
8702     VariantInit(&var);
8703     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8704     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
8705     VariantClear(&var);
8706
8707     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8708     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
8709     VariantClear(&var);
8710
8711     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8712     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8713
8714     hr = IXMLDOMDocument2_get_schemas(doc, &var);
8715     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
8716     VariantClear(&var);
8717 }
8718
8719 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8720 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8721 {
8722     VARIANT_BOOL b;
8723     VARIANT var;
8724
8725     VariantInit(&var);
8726     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
8727     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
8728     VariantClear(&var);
8729
8730     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
8731     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8732     VariantClear(&var);
8733
8734     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
8735     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8736
8737     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
8738     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8739     VariantClear(&var);
8740 }
8741
8742 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8743 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8744 {
8745     VARIANT var;
8746
8747     VariantInit(&var);
8748     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
8749     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
8750     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
8751     V_VT(&var) = VT_DISPATCH;
8752     V_DISPATCH(&var) = NULL;
8753     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
8754     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8755     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8756     VariantClear(&var);
8757 }
8758
8759 #define unset_props(doc) _unset_props(__LINE__, doc)
8760 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8761 {
8762     VARIANT var;
8763
8764     VariantInit(&var);
8765     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
8766     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
8767     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
8768     V_VT(&var) = VT_NULL;
8769     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
8770     VariantClear(&var);
8771 }
8772
8773 static void test_get_ownerDocument(void)
8774 {
8775     IXMLDOMDocument *doc1, *doc2, *doc3;
8776     IXMLDOMDocument2 *doc, *doc_owner;
8777     IXMLDOMNode *node;
8778     IXMLDOMSchemaCollection *cache;
8779     VARIANT_BOOL b;
8780     VARIANT var;
8781
8782     doc = create_document(&IID_IXMLDOMDocument2);
8783     cache = create_cache(&IID_IXMLDOMSchemaCollection);
8784     if (!doc || !cache)
8785     {
8786         if (doc) IXMLDOMDocument2_Release(doc);
8787         if (cache) IXMLDOMSchemaCollection_Release(cache);
8788         return;
8789     }
8790
8791     VariantInit(&var);
8792
8793     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8794     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8795
8796     check_default_props(doc);
8797
8798     /* set properties and check that new instances use them */
8799     set_props(doc, cache);
8800     check_set_props(doc);
8801
8802     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8803     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
8804
8805     /* new interface keeps props */
8806     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8807     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8808     check_set_props(doc_owner);
8809     IXMLDOMDocument2_Release(doc_owner);
8810
8811     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
8812     IXMLDOMNode_Release(node);
8813
8814     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8815
8816     /* reload */
8817     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
8818     ok(b == VARIANT_TRUE, "failed to load XML string\n");
8819
8820     /* properties retained even after reload */
8821     check_set_props(doc);
8822
8823     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
8824     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
8825     IXMLDOMNode_Release(node);
8826
8827     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
8828     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8829     check_set_props(doc_owner);
8830
8831     /* changing properties for one instance changes them for all */
8832     unset_props(doc_owner);
8833     check_default_props(doc_owner);
8834     check_default_props(doc);
8835
8836     IXMLDOMSchemaCollection_Release(cache);
8837     IXMLDOMDocument_Release(doc1);
8838     IXMLDOMDocument_Release(doc2);
8839     IXMLDOMDocument_Release(doc3);
8840     IXMLDOMDocument2_Release(doc);
8841     IXMLDOMDocument2_Release(doc_owner);
8842     free_bstrs();
8843 }
8844
8845 static void test_setAttributeNode(void)
8846 {
8847     IXMLDOMDocument *doc, *doc2;
8848     IXMLDOMElement *elem, *elem2;
8849     IXMLDOMAttribute *attr, *attr2, *ret_attr;
8850     VARIANT_BOOL b;
8851     HRESULT hr;
8852     VARIANT v;
8853     BSTR str;
8854     ULONG ref1, ref2;
8855
8856     doc = create_document(&IID_IXMLDOMDocument);
8857     if (!doc) return;
8858
8859     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8860     ok( hr == S_OK, "loadXML failed\n");
8861     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8862
8863     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8864     ok( hr == S_OK, "got 0x%08x\n", hr);
8865
8866     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8867     ok( hr == S_OK, "got 0x%08x\n", hr);
8868     ok( elem2 != elem, "got same instance\n");
8869
8870     ret_attr = (void*)0xdeadbeef;
8871     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8872     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8873     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8874
8875     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8876     ok( hr == S_OK, "got 0x%08x\n", hr);
8877
8878     ref1 = IXMLDOMElement_AddRef(elem);
8879     IXMLDOMElement_Release(elem);
8880
8881     ret_attr = (void*)0xdeadbeef;
8882     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8883     ok( hr == S_OK, "got 0x%08x\n", hr);
8884     ok( ret_attr == NULL, "got %p\n", ret_attr);
8885
8886     /* no reference added */
8887     ref2 = IXMLDOMElement_AddRef(elem);
8888     IXMLDOMElement_Release(elem);
8889     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8890
8891     EXPECT_CHILDREN(elem);
8892     EXPECT_CHILDREN(elem2);
8893
8894     IXMLDOMElement_Release(elem2);
8895
8896     attr2 = NULL;
8897     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8898     ok( hr == S_OK, "got 0x%08x\n", hr);
8899     ok( attr2 != attr, "got same instance %p\n", attr2);
8900     IXMLDOMAttribute_Release(attr2);
8901
8902     /* try to add it another time */
8903     ret_attr = (void*)0xdeadbeef;
8904     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8905     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8906     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8907
8908     IXMLDOMElement_Release(elem);
8909
8910     /* initially used element is released, attribute still 'has' a container */
8911     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8912     ok( hr == S_OK, "got 0x%08x\n", hr);
8913     ret_attr = (void*)0xdeadbeef;
8914     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8915     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8916     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8917     IXMLDOMElement_Release(elem);
8918
8919     /* add attribute already attached to another document */
8920     doc2 = create_document(&IID_IXMLDOMDocument);
8921
8922     hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8923     ok( hr == S_OK, "loadXML failed\n");
8924     ok( b == VARIANT_TRUE, "failed to load XML string\n");
8925
8926     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8927     ok( hr == S_OK, "got 0x%08x\n", hr);
8928     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8929     ok( hr == E_FAIL, "got 0x%08x\n", hr);
8930     IXMLDOMElement_Release(elem);
8931
8932     IXMLDOMAttribute_Release(attr);
8933
8934     /* create element, add attribute, see if it's copied or linked */
8935     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8936     ok( hr == S_OK, "got 0x%08x\n", hr);
8937
8938     attr = NULL;
8939     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8940     ok(hr == S_OK, "got 0x%08x\n", hr);
8941     ok(attr != NULL, "got %p\n", attr);
8942
8943     ref1 = IXMLDOMAttribute_AddRef(attr);
8944     IXMLDOMAttribute_Release(attr);
8945
8946     V_VT(&v) = VT_BSTR;
8947     V_BSTR(&v) = _bstr_("attrvalue1");
8948     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8949     ok( hr == S_OK, "got 0x%08x\n", hr);
8950
8951     str = NULL;
8952     hr = IXMLDOMAttribute_get_xml(attr, &str);
8953     ok( hr == S_OK, "got 0x%08x\n", hr);
8954     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8955         "got %s\n", wine_dbgstr_w(str));
8956     SysFreeString(str);
8957
8958     ret_attr = (void*)0xdeadbeef;
8959     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8960     ok(hr == S_OK, "got 0x%08x\n", hr);
8961     ok(ret_attr == NULL, "got %p\n", ret_attr);
8962
8963     /* attribute reference increased */
8964     ref2 = IXMLDOMAttribute_AddRef(attr);
8965     IXMLDOMAttribute_Release(attr);
8966     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8967
8968     hr = IXMLDOMElement_get_xml(elem, &str);
8969     ok( hr == S_OK, "got 0x%08x\n", hr);
8970     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8971         "got %s\n", wine_dbgstr_w(str));
8972     SysFreeString(str);
8973
8974     V_VT(&v) = VT_BSTR;
8975     V_BSTR(&v) = _bstr_("attrvalue2");
8976     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8977     ok( hr == S_OK, "got 0x%08x\n", hr);
8978
8979     hr = IXMLDOMElement_get_xml(elem, &str);
8980     ok( hr == S_OK, "got 0x%08x\n", hr);
8981     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8982         "got %s\n", wine_dbgstr_w(str));
8983     SysFreeString(str);
8984
8985     IXMLDOMElement_Release(elem);
8986     IXMLDOMAttribute_Release(attr);
8987     IXMLDOMDocument_Release(doc2);
8988     IXMLDOMDocument_Release(doc);
8989     free_bstrs();
8990 }
8991
8992 static void test_createNode(void)
8993 {
8994     IXMLDOMDocument *doc;
8995     IXMLDOMElement *elem;
8996     IXMLDOMNode *node;
8997     VARIANT v, var;
8998     BSTR prefix, str;
8999     HRESULT hr;
9000     ULONG ref;
9001
9002     doc = create_document(&IID_IXMLDOMDocument);
9003     if (!doc) return;
9004
9005     EXPECT_REF(doc, 1);
9006
9007     /* reference count tests */
9008     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9009     ok( hr == S_OK, "got 0x%08x\n", hr);
9010
9011     /* initial reference is 2 */
9012 todo_wine {
9013     EXPECT_REF(elem, 2);
9014     ref = IXMLDOMElement_Release(elem);
9015     ok(ref == 1, "got %d\n", ref);
9016     /* it's released already, attempt to release now will crash it */
9017 }
9018
9019     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9020     ok( hr == S_OK, "got 0x%08x\n", hr);
9021     todo_wine EXPECT_REF(elem, 2);
9022     IXMLDOMDocument_Release(doc);
9023     todo_wine EXPECT_REF(elem, 2);
9024     IXMLDOMElement_Release(elem);
9025
9026     doc = create_document(&IID_IXMLDOMDocument);
9027
9028     /* NODE_ELEMENT nodes */
9029     /* 1. specified namespace */
9030     V_VT(&v) = VT_I4;
9031     V_I4(&v) = NODE_ELEMENT;
9032
9033     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
9034     ok( hr == S_OK, "got 0x%08x\n", hr);
9035     prefix = NULL;
9036     hr = IXMLDOMNode_get_prefix(node, &prefix);
9037     ok( hr == S_OK, "got 0x%08x\n", hr);
9038     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
9039     SysFreeString(prefix);
9040     IXMLDOMNode_Release(node);
9041
9042     /* 2. default namespace */
9043     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
9044     ok( hr == S_OK, "got 0x%08x\n", hr);
9045     prefix = (void*)0xdeadbeef;
9046     hr = IXMLDOMNode_get_prefix(node, &prefix);
9047     ok( hr == S_FALSE, "got 0x%08x\n", hr);
9048     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
9049     /* check dump */
9050     hr = IXMLDOMNode_get_xml(node, &str);
9051     ok( hr == S_OK, "got 0x%08x\n", hr);
9052     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
9053         "got %s\n", wine_dbgstr_w(str));
9054     SysFreeString(str);
9055
9056     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
9057     ok( hr == S_OK, "got 0x%08x\n", hr);
9058
9059     V_VT(&var) = VT_BSTR;
9060     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
9061     ok( hr == S_FALSE, "got 0x%08x\n", hr);
9062     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
9063
9064     str = NULL;
9065     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
9066     ok( hr == S_OK, "got 0x%08x\n", hr);
9067     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
9068     SysFreeString(str);
9069
9070     IXMLDOMElement_Release(elem);
9071     IXMLDOMNode_Release(node);
9072
9073     IXMLDOMDocument_Release(doc);
9074     free_bstrs();
9075 }
9076
9077 static const char get_prefix_doc[] =
9078     "<?xml version=\"1.0\" ?>"
9079     "<a xmlns:ns1=\"ns1 href\" />";
9080
9081 static void test_get_prefix(void)
9082 {
9083     IXMLDOMDocumentFragment *fragment;
9084     IXMLDOMCDATASection *cdata;
9085     IXMLDOMElement *element;
9086     IXMLDOMComment *comment;
9087     IXMLDOMDocument *doc;
9088     VARIANT_BOOL b;
9089     HRESULT hr;
9090     BSTR str;
9091
9092     doc = create_document(&IID_IXMLDOMDocument);
9093     if (!doc) return;
9094
9095     /* nodes that can't support prefix */
9096     /* 1. document */
9097     str = (void*)0xdeadbeef;
9098     hr = IXMLDOMDocument_get_prefix(doc, &str);
9099     EXPECT_HR(hr, S_FALSE);
9100     ok(str == NULL, "got %p\n", str);
9101
9102     hr = IXMLDOMDocument_get_prefix(doc, NULL);
9103     EXPECT_HR(hr, E_INVALIDARG);
9104
9105     /* 2. cdata */
9106     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
9107     ok(hr == S_OK, "got %08x\n", hr );
9108
9109     str = (void*)0xdeadbeef;
9110     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
9111     ok(hr == S_FALSE, "got %08x\n", hr);
9112     ok( str == 0, "got %p\n", str);
9113
9114     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
9115     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9116     IXMLDOMCDATASection_Release(cdata);
9117
9118     /* 3. comment */
9119     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
9120     ok(hr == S_OK, "got %08x\n", hr );
9121
9122     str = (void*)0xdeadbeef;
9123     hr = IXMLDOMComment_get_prefix(comment, &str);
9124     ok(hr == S_FALSE, "got %08x\n", hr);
9125     ok( str == 0, "got %p\n", str);
9126
9127     hr = IXMLDOMComment_get_prefix(comment, NULL);
9128     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9129     IXMLDOMComment_Release(comment);
9130
9131     /* 4. fragment */
9132     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
9133     ok(hr == S_OK, "got %08x\n", hr );
9134
9135     str = (void*)0xdeadbeef;
9136     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
9137     ok(hr == S_FALSE, "got %08x\n", hr);
9138     ok( str == 0, "got %p\n", str);
9139
9140     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
9141     ok(hr == E_INVALIDARG, "got %08x\n", hr);
9142     IXMLDOMDocumentFragment_Release(fragment);
9143
9144     /* no prefix */
9145     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
9146     ok( hr == S_OK, "got 0x%08x\n", hr);
9147
9148     hr = IXMLDOMElement_get_prefix(element, NULL);
9149     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
9150
9151     str = (void*)0xdeadbeef;
9152     hr = IXMLDOMElement_get_prefix(element, &str);
9153     ok( hr == S_FALSE, "got 0x%08x\n", hr);
9154     ok( str == 0, "got %p\n", str);
9155
9156     IXMLDOMElement_Release(element);
9157
9158     /* with prefix */
9159     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
9160     ok( hr == S_OK, "got 0x%08x\n", hr);
9161
9162     str = (void*)0xdeadbeef;
9163     hr = IXMLDOMElement_get_prefix(element, &str);
9164     ok( hr == S_OK, "got 0x%08x\n", hr);
9165     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
9166     SysFreeString(str);
9167
9168     str = (void*)0xdeadbeef;
9169     hr = IXMLDOMElement_get_namespaceURI(element, &str);
9170     ok( hr == S_FALSE, "got 0x%08x\n", hr);
9171     ok( str == 0, "got %p\n", str);
9172
9173     IXMLDOMElement_Release(element);
9174
9175     hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
9176     EXPECT_HR(hr, S_OK);
9177
9178     hr = IXMLDOMDocument_get_documentElement(doc, &element);
9179     EXPECT_HR(hr, S_OK);
9180
9181     str = (void*)0xdeadbeef;
9182     hr = IXMLDOMElement_get_prefix(element, &str);
9183     EXPECT_HR(hr, S_FALSE);
9184     ok(str == NULL, "got %p\n", str);
9185
9186     str = (void*)0xdeadbeef;
9187     hr = IXMLDOMElement_get_namespaceURI(element, &str);
9188     EXPECT_HR(hr, S_FALSE);
9189     ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
9190
9191     IXMLDOMDocument_Release(doc);
9192     free_bstrs();
9193 }
9194
9195 static void test_selectSingleNode(void)
9196 {
9197     IXMLDOMDocument *doc;
9198     IXMLDOMNodeList *list;
9199     IXMLDOMNode *node;
9200     VARIANT_BOOL b;
9201     HRESULT hr;
9202     LONG len;
9203
9204     doc = create_document(&IID_IXMLDOMDocument);
9205     if (!doc) return;
9206
9207     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
9208     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9209
9210     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
9211     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9212
9213     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
9214     ok( hr == S_OK, "loadXML failed\n");
9215     ok( b == VARIANT_TRUE, "failed to load XML string\n");
9216
9217     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
9218     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9219
9220     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
9221     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9222
9223     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
9224     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9225
9226     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
9227     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9228
9229     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
9230     ok(hr == S_OK, "got 0x%08x\n", hr);
9231     IXMLDOMNode_Release(node);
9232
9233     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
9234     ok(hr == S_OK, "got 0x%08x\n", hr);
9235     IXMLDOMNodeList_Release(list);
9236
9237     list = (void*)0xdeadbeef;
9238     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
9239     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9240     ok(list == (void*)0xdeadbeef, "got %p\n", list);
9241
9242     node = (void*)0xdeadbeef;
9243     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
9244     ok(hr == S_FALSE, "got 0x%08x\n", hr);
9245     ok(node == 0, "got %p\n", node);
9246
9247     list = (void*)0xdeadbeef;
9248     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
9249     ok(hr == S_OK, "got 0x%08x\n", hr);
9250     len = 1;
9251     hr = IXMLDOMNodeList_get_length(list, &len);
9252     ok(hr == S_OK, "got 0x%08x\n", hr);
9253     ok(len == 0, "got %d\n", len);
9254     IXMLDOMNodeList_Release(list);
9255
9256     IXMLDOMDocument_Release(doc);
9257     free_bstrs();
9258 }
9259
9260 static void test_events(void)
9261 {
9262     IConnectionPointContainer *conn;
9263     IConnectionPoint *point;
9264     IXMLDOMDocument *doc;
9265     HRESULT hr;
9266     VARIANT v;
9267     IDispatch *event;
9268
9269     doc = create_document(&IID_IXMLDOMDocument);
9270     if (!doc) return;
9271
9272     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
9273     ok(hr == S_OK, "got 0x%08x\n", hr);
9274
9275     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
9276     ok(hr == S_OK, "got 0x%08x\n", hr);
9277     IConnectionPoint_Release(point);
9278     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
9279     ok(hr == S_OK, "got 0x%08x\n", hr);
9280     IConnectionPoint_Release(point);
9281     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
9282     ok(hr == S_OK, "got 0x%08x\n", hr);
9283     IConnectionPoint_Release(point);
9284
9285     IConnectionPointContainer_Release(conn);
9286
9287     /* ready state callback */
9288     VariantInit(&v);
9289     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9290     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9291
9292     event = create_dispevent();
9293     V_VT(&v) = VT_UNKNOWN;
9294     V_UNKNOWN(&v) = (IUnknown*)event;
9295
9296     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9297     ok(hr == S_OK, "got 0x%08x\n", hr);
9298     EXPECT_REF(event, 2);
9299
9300     V_VT(&v) = VT_DISPATCH;
9301     V_DISPATCH(&v) = event;
9302
9303     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9304     ok(hr == S_OK, "got 0x%08x\n", hr);
9305     EXPECT_REF(event, 2);
9306
9307     /* VT_NULL doesn't reset event handler */
9308     V_VT(&v) = VT_NULL;
9309     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9310     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
9311     EXPECT_REF(event, 2);
9312
9313     V_VT(&v) = VT_DISPATCH;
9314     V_DISPATCH(&v) = NULL;
9315
9316     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9317     ok(hr == S_OK, "got 0x%08x\n", hr);
9318     EXPECT_REF(event, 1);
9319
9320     V_VT(&v) = VT_UNKNOWN;
9321     V_DISPATCH(&v) = NULL;
9322     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
9323     ok(hr == S_OK, "got 0x%08x\n", hr);
9324
9325     IDispatch_Release(event);
9326
9327     IXMLDOMDocument_Release(doc);
9328 }
9329
9330 static void test_createProcessingInstruction(void)
9331 {
9332     static const WCHAR bodyW[] = {'t','e','s','t',0};
9333     IXMLDOMProcessingInstruction *pi;
9334     IXMLDOMDocument *doc;
9335     WCHAR buff[10];
9336     HRESULT hr;
9337
9338     doc = create_document(&IID_IXMLDOMDocument);
9339     if (!doc) return;
9340
9341     /* test for BSTR handling, pass broken BSTR */
9342     memcpy(&buff[2], bodyW, sizeof(bodyW));
9343     /* just a big length */
9344     *(DWORD*)buff = 0xf0f0;
9345     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
9346     ok(hr == S_OK, "got 0x%08x\n", hr);
9347
9348     IXMLDOMProcessingInstruction_Release(pi);
9349     IXMLDOMDocument_Release(doc);
9350 }
9351
9352 static void test_put_nodeTypedValue(void)
9353 {
9354     static const BYTE binhexdata[16] =
9355         {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
9356     IXMLDOMDocument *doc;
9357     IXMLDOMElement *elem;
9358     VARIANT type, value;
9359     LONG ubound, lbound;
9360     IXMLDOMNode *node;
9361     SAFEARRAY *array;
9362     HRESULT hr;
9363     BYTE *ptr;
9364     BSTR str;
9365
9366     doc = create_document(&IID_IXMLDOMDocument);
9367     if (!doc) return;
9368
9369     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9370     EXPECT_HR(hr, S_OK);
9371
9372     V_VT(&type) = VT_EMPTY;
9373     hr = IXMLDOMElement_get_dataType(elem, &type);
9374     EXPECT_HR(hr, S_FALSE);
9375     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9376
9377     /* set typed value for untyped node */
9378     V_VT(&type) = VT_I1;
9379     V_I1(&type) = 1;
9380     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9381     EXPECT_HR(hr, S_OK);
9382
9383     V_VT(&type) = VT_EMPTY;
9384     hr = IXMLDOMElement_get_dataType(elem, &type);
9385     EXPECT_HR(hr, S_FALSE);
9386     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9387
9388     /* no type info stored */
9389     V_VT(&type) = VT_EMPTY;
9390     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9391     EXPECT_HR(hr, S_OK);
9392     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9393     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
9394        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9395     VariantClear(&type);
9396
9397     hr = IXMLDOMElement_get_firstChild(elem, &node);
9398     EXPECT_HR(hr, S_OK);
9399     hr = IXMLDOMElement_removeChild(elem, node, NULL);
9400     EXPECT_HR(hr, S_OK);
9401     IXMLDOMNode_Release(node);
9402
9403     hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)elem, NULL);
9404     EXPECT_HR(hr, S_OK);
9405
9406     /* bin.base64 */
9407     hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.base64"));
9408     EXPECT_HR(hr, S_OK);
9409
9410     V_VT(&value) = VT_BSTR;
9411     V_BSTR(&value) = _bstr_("ABCD");
9412     hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9413     EXPECT_HR(hr, S_OK);
9414
9415     V_VT(&value) = VT_EMPTY;
9416     hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9417     EXPECT_HR(hr, S_OK);
9418     ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9419     ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9420     ubound = 0;
9421     hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9422     EXPECT_HR(hr, S_OK);
9423     ok(ubound == 2, "got %d\n", ubound);
9424     lbound = 0;
9425     hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9426     EXPECT_HR(hr, S_OK);
9427     ok(lbound == 0, "got %d\n", lbound);
9428     hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9429     EXPECT_HR(hr, S_OK);
9430     ok(ptr[0] == 0, "got %x\n", ptr[0]);
9431     ok(ptr[1] == 0x10, "got %x\n", ptr[1]);
9432     ok(ptr[2] == 0x83, "got %x\n", ptr[2]);
9433     SafeArrayUnaccessData(V_ARRAY(&value));
9434     VariantClear(&value);
9435
9436     /* when set as VT_BSTR it's stored as is */
9437     hr = IXMLDOMElement_get_firstChild(elem, &node);
9438     EXPECT_HR(hr, S_OK);
9439     hr = IXMLDOMNode_get_text(node, &str);
9440     EXPECT_HR(hr, S_OK);
9441     ok(!lstrcmpW(str, _bstr_("ABCD")), "%s\n", wine_dbgstr_w(str));
9442     IXMLDOMNode_Release(node);
9443
9444     array = SafeArrayCreateVector(VT_UI1, 0, 7);
9445     hr = SafeArrayAccessData(array, (void*)&ptr);
9446     EXPECT_HR(hr, S_OK);
9447     memcpy(ptr, "dGVzdA=", strlen("dGVzdA="));
9448     SafeArrayUnaccessData(array);
9449
9450     V_VT(&value) = VT_UI1|VT_ARRAY;
9451     V_ARRAY(&value) = array;
9452     hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9453     EXPECT_HR(hr, S_OK);
9454
9455     V_VT(&value) = VT_EMPTY;
9456     hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9457     EXPECT_HR(hr, S_OK);
9458     ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9459     ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9460     ubound = 0;
9461     hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9462     EXPECT_HR(hr, S_OK);
9463     ok(ubound == 6, "got %d\n", ubound);
9464     lbound = 0;
9465     hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9466     EXPECT_HR(hr, S_OK);
9467     ok(lbound == 0, "got %d\n", lbound);
9468     hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9469     EXPECT_HR(hr, S_OK);
9470     ok(!memcmp(ptr, "dGVzdA=", strlen("dGVzdA=")), "got wrong data, %s\n", ptr);
9471     SafeArrayUnaccessData(V_ARRAY(&value));
9472     VariantClear(&value);
9473
9474     /* if set with VT_UI1|VT_ARRAY it's encoded */
9475     hr = IXMLDOMElement_get_firstChild(elem, &node);
9476     EXPECT_HR(hr, S_OK);
9477     hr = IXMLDOMNode_get_text(node, &str);
9478     EXPECT_HR(hr, S_OK);
9479     ok(!lstrcmpW(str, _bstr_("ZEdWemRBPQ==")), "%s\n", wine_dbgstr_w(str));
9480     IXMLDOMNode_Release(node);
9481     SafeArrayDestroyData(array);
9482
9483     /* bin.hex */
9484     V_VT(&value) = VT_BSTR;
9485     V_BSTR(&value) = _bstr_("");
9486     hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9487     EXPECT_HR(hr, S_OK);
9488
9489     hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.hex"));
9490     EXPECT_HR(hr, S_OK);
9491
9492     array = SafeArrayCreateVector(VT_UI1, 0, 16);
9493     hr = SafeArrayAccessData(array, (void*)&ptr);
9494     EXPECT_HR(hr, S_OK);
9495     memcpy(ptr, binhexdata, sizeof(binhexdata));
9496     SafeArrayUnaccessData(array);
9497
9498     V_VT(&value) = VT_UI1|VT_ARRAY;
9499     V_ARRAY(&value) = array;
9500     hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9501     EXPECT_HR(hr, S_OK);
9502
9503     V_VT(&value) = VT_EMPTY;
9504     hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9505     EXPECT_HR(hr, S_OK);
9506     ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9507     ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9508     ubound = 0;
9509     hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9510     EXPECT_HR(hr, S_OK);
9511     ok(ubound == 15, "got %d\n", ubound);
9512     lbound = 0;
9513     hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9514     EXPECT_HR(hr, S_OK);
9515     ok(lbound == 0, "got %d\n", lbound);
9516     hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9517     EXPECT_HR(hr, S_OK);
9518     ok(!memcmp(ptr, binhexdata, sizeof(binhexdata)), "got wrong data\n");
9519     SafeArrayUnaccessData(V_ARRAY(&value));
9520     VariantClear(&value);
9521
9522     /* if set with VT_UI1|VT_ARRAY it's encoded */
9523     hr = IXMLDOMElement_get_firstChild(elem, &node);
9524     EXPECT_HR(hr, S_OK);
9525     hr = IXMLDOMNode_get_text(node, &str);
9526     EXPECT_HR(hr, S_OK);
9527     ok(!lstrcmpW(str, _bstr_("000102030405060708090a0b0c0d0e0f")), "%s\n", wine_dbgstr_w(str));
9528     IXMLDOMNode_Release(node);
9529     SafeArrayDestroyData(array);
9530
9531     IXMLDOMElement_Release(elem);
9532     IXMLDOMDocument_Release(doc);
9533     free_bstrs();
9534 }
9535
9536 static void test_get_xml(void)
9537 {
9538     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9539     static const char fooA[] = "<foo/>";
9540     IXMLDOMProcessingInstruction *pi;
9541     IXMLDOMNode *first;
9542     IXMLDOMElement *elem = NULL;
9543     IXMLDOMDocument *doc;
9544     VARIANT_BOOL b;
9545     VARIANT v;
9546     BSTR xml;
9547     HRESULT hr;
9548
9549     doc = create_document(&IID_IXMLDOMDocument);
9550     if (!doc) return;
9551
9552     b = VARIANT_TRUE;
9553     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9554     ok(hr == S_OK, "got 0x%08x\n", hr);
9555     ok( b == VARIANT_TRUE, "got %d\n", b);
9556
9557     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9558                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9559     ok(hr == S_OK, "got 0x%08x\n", hr);
9560
9561     hr = IXMLDOMDocument_get_firstChild(doc, &first);
9562     ok(hr == S_OK, "got 0x%08x\n", hr);
9563
9564     V_UNKNOWN(&v) = (IUnknown*)first;
9565     V_VT(&v) = VT_UNKNOWN;
9566
9567     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9568     ok(hr == S_OK, "got 0x%08x\n", hr);
9569
9570     IXMLDOMProcessingInstruction_Release(pi);
9571     IXMLDOMNode_Release(first);
9572
9573     hr = IXMLDOMDocument_get_xml(doc, &xml);
9574     ok(hr == S_OK, "got 0x%08x\n", hr);
9575
9576     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9577         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9578     SysFreeString(xml);
9579
9580     IXMLDOMDocument_Release(doc);
9581
9582     doc = create_document(&IID_IXMLDOMDocument);
9583
9584     hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9585     ok(hr == S_OK, "got 0x%08x\n", hr);
9586
9587     hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9588     ok(hr == S_OK, "got 0x%08x\n", hr);
9589
9590     hr = IXMLDOMDocument_get_xml(doc, &xml);
9591     ok(hr == S_OK, "got 0x%08x\n", hr);
9592
9593     ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9594         "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9595     SysFreeString(xml);
9596
9597     IXMLDOMElement_Release(elem);
9598     IXMLDOMDocument_Release(doc);
9599
9600     free_bstrs();
9601 }
9602
9603 static void test_xsltemplate(void)
9604 {
9605     IXSLTemplate *template;
9606     IXSLProcessor *processor;
9607     IXMLDOMDocument *doc, *doc2;
9608     IStream *stream;
9609     VARIANT_BOOL b;
9610     HRESULT hr;
9611     ULONG ref1, ref2;
9612     VARIANT v;
9613
9614     template = create_xsltemplate(&IID_IXSLTemplate);
9615     if (!template) return;
9616
9617     /* works as reset */
9618     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9619     ok(hr == S_OK, "got 0x%08x\n", hr);
9620
9621     doc = create_document(&IID_IXMLDOMDocument);
9622
9623     b = VARIANT_TRUE;
9624     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9625     ok(hr == S_OK, "got 0x%08x\n", hr);
9626     ok( b == VARIANT_TRUE, "got %d\n", b);
9627
9628     /* putref with non-xsl document */
9629     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9630     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9631
9632     b = VARIANT_TRUE;
9633     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9634     ok(hr == S_OK, "got 0x%08x\n", hr);
9635     ok( b == VARIANT_TRUE, "got %d\n", b);
9636
9637     /* not a freethreaded document */
9638     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9639     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
9640
9641     IXMLDOMDocument_Release(doc);
9642
9643     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9644     if (hr != S_OK)
9645     {
9646         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
9647         IXSLTemplate_Release(template);
9648         return;
9649     }
9650
9651     b = VARIANT_TRUE;
9652     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9653     ok(hr == S_OK, "got 0x%08x\n", hr);
9654     ok( b == VARIANT_TRUE, "got %d\n", b);
9655
9656     /* freethreaded document */
9657     ref1 = IXMLDOMDocument_AddRef(doc);
9658     IXMLDOMDocument_Release(doc);
9659     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9660     ok(hr == S_OK, "got 0x%08x\n", hr);
9661     ref2 = IXMLDOMDocument_AddRef(doc);
9662     IXMLDOMDocument_Release(doc);
9663     ok(ref2 > ref1, "got %d\n", ref2);
9664
9665     /* processor */
9666     hr = IXSLTemplate_createProcessor(template, NULL);
9667     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9668
9669     EXPECT_REF(template, 1);
9670     hr = IXSLTemplate_createProcessor(template, &processor);
9671     ok(hr == S_OK, "got 0x%08x\n", hr);
9672     EXPECT_REF(template, 2);
9673
9674     /* input no set yet */
9675     V_VT(&v) = VT_BSTR;
9676     V_BSTR(&v) = NULL;
9677     hr = IXSLProcessor_get_input(processor, &v);
9678 todo_wine {
9679     ok(hr == S_OK, "got 0x%08x\n", hr);
9680     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9681 }
9682
9683     hr = IXSLProcessor_get_output(processor, NULL);
9684     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9685
9686     /* reset before it was set */
9687     V_VT(&v) = VT_EMPTY;
9688     hr = IXSLProcessor_put_output(processor, v);
9689     ok(hr == S_OK, "got 0x%08x\n", hr);
9690
9691     CreateStreamOnHGlobal(NULL, TRUE, &stream);
9692     EXPECT_REF(stream, 1);
9693
9694     V_VT(&v) = VT_UNKNOWN;
9695     V_UNKNOWN(&v) = (IUnknown*)stream;
9696     hr = IXSLProcessor_put_output(processor, v);
9697     ok(hr == S_OK, "got 0x%08x\n", hr);
9698
9699     /* it seems processor grabs 2 references */
9700     todo_wine EXPECT_REF(stream, 3);
9701
9702     V_VT(&v) = VT_EMPTY;
9703     hr = IXSLProcessor_get_output(processor, &v);
9704     ok(hr == S_OK, "got 0x%08x\n", hr);
9705     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9706     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9707
9708     todo_wine EXPECT_REF(stream, 4);
9709     VariantClear(&v);
9710
9711     hr = IXSLProcessor_transform(processor, NULL);
9712     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9713
9714     /* reset and check stream refcount */
9715     V_VT(&v) = VT_EMPTY;
9716     hr = IXSLProcessor_put_output(processor, v);
9717     ok(hr == S_OK, "got 0x%08x\n", hr);
9718
9719     EXPECT_REF(stream, 1);
9720
9721     IStream_Release(stream);
9722
9723     /* no output interface set, check output */
9724     doc2 = create_document(&IID_IXMLDOMDocument);
9725
9726     b = VARIANT_TRUE;
9727     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9728     ok(hr == S_OK, "got 0x%08x\n", hr);
9729     ok( b == VARIANT_TRUE, "got %d\n", b);
9730
9731     V_VT(&v) = VT_UNKNOWN;
9732     V_UNKNOWN(&v) = (IUnknown*)doc2;
9733     hr = IXSLProcessor_put_input(processor, v);
9734     ok(hr == S_OK, "got 0x%08x\n", hr);
9735
9736     hr = IXSLProcessor_transform(processor, &b);
9737     ok(hr == S_OK, "got 0x%08x\n", hr);
9738
9739     V_VT(&v) = VT_EMPTY;
9740     hr = IXSLProcessor_get_output(processor, &v);
9741     ok(hr == S_OK, "got 0x%08x\n", hr);
9742     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9743     ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9744     IXMLDOMDocument_Release(doc2);
9745     VariantClear(&v);
9746
9747     IXSLProcessor_Release(processor);
9748
9749     /* drop reference */
9750     hr = IXSLTemplate_putref_stylesheet(template, NULL);
9751     ok(hr == S_OK, "got 0x%08x\n", hr);
9752     ref2 = IXMLDOMDocument_AddRef(doc);
9753     IXMLDOMDocument_Release(doc);
9754     ok(ref2 == ref1, "got %d\n", ref2);
9755
9756     IXMLDOMDocument_Release(doc);
9757     IXSLTemplate_Release(template);
9758     free_bstrs();
9759 }
9760
9761 static void test_insertBefore(void)
9762 {
9763     IXMLDOMDocument *doc, *doc2;
9764     IXMLDOMAttribute *attr;
9765     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9766     IXMLDOMNode *node, *newnode;
9767     HRESULT hr;
9768     VARIANT v;
9769     BSTR p;
9770
9771     doc = create_document(&IID_IXMLDOMDocument);
9772
9773     /* insertBefore behaviour for attribute node */
9774     V_VT(&v) = VT_I4;
9775     V_I4(&v) = NODE_ATTRIBUTE;
9776
9777     attr = NULL;
9778     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9779     ok(hr == S_OK, "got 0x%08x\n", hr);
9780     ok(attr != NULL, "got %p\n", attr);
9781
9782     /* attribute to attribute */
9783     V_VT(&v) = VT_I4;
9784     V_I4(&v) = NODE_ATTRIBUTE;
9785     newnode = NULL;
9786     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9787     ok(hr == S_OK, "got 0x%08x\n", hr);
9788     ok(newnode != NULL, "got %p\n", newnode);
9789
9790     V_VT(&v) = VT_NULL;
9791     node = (void*)0xdeadbeef;
9792     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9793     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9794     ok(node == NULL, "got %p\n", node);
9795
9796     V_VT(&v) = VT_UNKNOWN;
9797     V_UNKNOWN(&v) = (IUnknown*)attr;
9798     node = (void*)0xdeadbeef;
9799     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9800     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9801     ok(node == NULL, "got %p\n", node);
9802     IXMLDOMNode_Release(newnode);
9803
9804     /* cdata to attribute */
9805     V_VT(&v) = VT_I4;
9806     V_I4(&v) = NODE_CDATA_SECTION;
9807     newnode = NULL;
9808     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9809     ok(hr == S_OK, "got 0x%08x\n", hr);
9810     ok(newnode != NULL, "got %p\n", newnode);
9811
9812     V_VT(&v) = VT_NULL;
9813     node = (void*)0xdeadbeef;
9814     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9815     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9816     ok(node == NULL, "got %p\n", node);
9817     IXMLDOMNode_Release(newnode);
9818
9819     /* comment to attribute */
9820     V_VT(&v) = VT_I4;
9821     V_I4(&v) = NODE_COMMENT;
9822     newnode = NULL;
9823     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9824     ok(hr == S_OK, "got 0x%08x\n", hr);
9825     ok(newnode != NULL, "got %p\n", newnode);
9826
9827     V_VT(&v) = VT_NULL;
9828     node = (void*)0xdeadbeef;
9829     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9830     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9831     ok(node == NULL, "got %p\n", node);
9832     IXMLDOMNode_Release(newnode);
9833
9834     /* element to attribute */
9835     V_VT(&v) = VT_I4;
9836     V_I4(&v) = NODE_ELEMENT;
9837     newnode = NULL;
9838     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9839     ok(hr == S_OK, "got 0x%08x\n", hr);
9840     ok(newnode != NULL, "got %p\n", newnode);
9841
9842     V_VT(&v) = VT_NULL;
9843     node = (void*)0xdeadbeef;
9844     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9845     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9846     ok(node == NULL, "got %p\n", node);
9847     IXMLDOMNode_Release(newnode);
9848
9849     /* pi to attribute */
9850     V_VT(&v) = VT_I4;
9851     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9852     newnode = NULL;
9853     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9854     ok(hr == S_OK, "got 0x%08x\n", hr);
9855     ok(newnode != NULL, "got %p\n", newnode);
9856
9857     V_VT(&v) = VT_NULL;
9858     node = (void*)0xdeadbeef;
9859     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9860     ok(hr == E_FAIL, "got 0x%08x\n", hr);
9861     ok(node == NULL, "got %p\n", node);
9862     IXMLDOMNode_Release(newnode);
9863     IXMLDOMAttribute_Release(attr);
9864
9865     /* insertBefore for elements */
9866     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9867     ok(hr == S_OK, "got 0x%08x\n", hr);
9868
9869     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9870     ok(hr == S_OK, "got 0x%08x\n", hr);
9871
9872     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9873     ok(hr == S_OK, "got 0x%08x\n", hr);
9874
9875     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9876     ok(hr == S_OK, "got 0x%08x\n", hr);
9877
9878     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9879     ok(hr == S_OK, "got 0x%08x\n", hr);
9880
9881     EXPECT_NO_CHILDREN(elem1);
9882     EXPECT_NO_CHILDREN(elem2);
9883     EXPECT_NO_CHILDREN(elem3);
9884
9885     todo_wine EXPECT_REF(elem2, 2);
9886
9887     V_VT(&v) = VT_DISPATCH;
9888     V_DISPATCH(&v) = NULL;
9889     node = NULL;
9890     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9891     ok(hr == S_OK, "got 0x%08x\n", hr);
9892     ok(node == (void*)elem4, "got %p\n", node);
9893
9894     EXPECT_CHILDREN(elem1);
9895     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9896     EXPECT_HR(hr, S_OK);
9897     IXMLDOMElement_Release(elem4);
9898
9899     EXPECT_NO_CHILDREN(elem1);
9900
9901     V_VT(&v) = VT_NULL;
9902     node = NULL;
9903     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9904     ok(hr == S_OK, "got 0x%08x\n", hr);
9905     ok(node == (void*)elem2, "got %p\n", node);
9906
9907     EXPECT_CHILDREN(elem1);
9908     todo_wine EXPECT_REF(elem2, 3);
9909     IXMLDOMNode_Release(node);
9910
9911     /* again for already linked node */
9912     V_VT(&v) = VT_NULL;
9913     node = NULL;
9914     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9915     ok(hr == S_OK, "got 0x%08x\n", hr);
9916     ok(node == (void*)elem2, "got %p\n", node);
9917
9918     EXPECT_CHILDREN(elem1);
9919
9920     /* increments each time */
9921     todo_wine EXPECT_REF(elem2, 3);
9922     IXMLDOMNode_Release(node);
9923
9924     /* try to add to another element */
9925     V_VT(&v) = VT_NULL;
9926     node = (void*)0xdeadbeef;
9927     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9928     ok(hr == S_OK, "got 0x%08x\n", hr);
9929     ok(node == (void*)elem2, "got %p\n", node);
9930
9931     EXPECT_CHILDREN(elem3);
9932     EXPECT_NO_CHILDREN(elem1);
9933
9934     IXMLDOMNode_Release(node);
9935
9936     /* cross document case - try to add as child to a node created with other doc */
9937     doc2 = create_document(&IID_IXMLDOMDocument);
9938
9939     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9940     ok(hr == S_OK, "got 0x%08x\n", hr);
9941     todo_wine EXPECT_REF(elem4, 2);
9942
9943     /* same name, another instance */
9944     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9945     ok(hr == S_OK, "got 0x%08x\n", hr);
9946     todo_wine EXPECT_REF(elem5, 2);
9947
9948     todo_wine EXPECT_REF(elem3, 2);
9949     V_VT(&v) = VT_NULL;
9950     node = NULL;
9951     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9952     ok(hr == S_OK, "got 0x%08x\n", hr);
9953     ok(node == (void*)elem4, "got %p\n", node);
9954     todo_wine EXPECT_REF(elem4, 3);
9955     todo_wine EXPECT_REF(elem3, 2);
9956     IXMLDOMNode_Release(node);
9957
9958     V_VT(&v) = VT_NULL;
9959     node = NULL;
9960     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9961     ok(hr == S_OK, "got 0x%08x\n", hr);
9962     ok(node == (void*)elem5, "got %p\n", node);
9963     todo_wine EXPECT_REF(elem4, 2);
9964     todo_wine EXPECT_REF(elem5, 3);
9965     IXMLDOMNode_Release(node);
9966
9967     IXMLDOMDocument_Release(doc2);
9968
9969     IXMLDOMElement_Release(elem1);
9970     IXMLDOMElement_Release(elem2);
9971     IXMLDOMElement_Release(elem3);
9972     IXMLDOMElement_Release(elem4);
9973     IXMLDOMElement_Release(elem5);
9974
9975     /* elements with same default namespace */
9976     V_VT(&v) = VT_I4;
9977     V_I4(&v) = NODE_ELEMENT;
9978     elem1 = NULL;
9979     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9980     ok(hr == S_OK, "got 0x%08x\n", hr);
9981     ok(elem1 != NULL, "got %p\n", elem1);
9982
9983     V_VT(&v) = VT_I4;
9984     V_I4(&v) = NODE_ELEMENT;
9985     elem2 = NULL;
9986     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9987     ok(hr == S_OK, "got 0x%08x\n", hr);
9988     ok(elem2 != NULL, "got %p\n", elem2);
9989
9990     /* check contents so far */
9991     p = NULL;
9992     hr = IXMLDOMElement_get_xml(elem1, &p);
9993     ok(hr == S_OK, "got 0x%08x\n", hr);
9994     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9995     SysFreeString(p);
9996
9997     p = NULL;
9998     hr = IXMLDOMElement_get_xml(elem2, &p);
9999     ok(hr == S_OK, "got 0x%08x\n", hr);
10000     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
10001     SysFreeString(p);
10002
10003     V_VT(&v) = VT_NULL;
10004     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
10005     ok(hr == S_OK, "got 0x%08x\n", hr);
10006
10007     /* get_xml depends on context, for top node it omits child namespace attribute,
10008        but at child level it's still returned */
10009     p = NULL;
10010     hr = IXMLDOMElement_get_xml(elem1, &p);
10011     ok(hr == S_OK, "got 0x%08x\n", hr);
10012     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
10013         "got %s\n", wine_dbgstr_w(p));
10014     SysFreeString(p);
10015
10016     p = NULL;
10017     hr = IXMLDOMElement_get_xml(elem2, &p);
10018     ok(hr == S_OK, "got 0x%08x\n", hr);
10019     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
10020     SysFreeString(p);
10021
10022     IXMLDOMElement_Release(elem1);
10023     IXMLDOMElement_Release(elem2);
10024
10025     /* child without default namespace added to node with default namespace */
10026     V_VT(&v) = VT_I4;
10027     V_I4(&v) = NODE_ELEMENT;
10028     elem1 = NULL;
10029     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
10030     ok(hr == S_OK, "got 0x%08x\n", hr);
10031     ok(elem1 != NULL, "got %p\n", elem1);
10032
10033     V_VT(&v) = VT_I4;
10034     V_I4(&v) = NODE_ELEMENT;
10035     elem2 = NULL;
10036     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
10037     ok(hr == S_OK, "got 0x%08x\n", hr);
10038     ok(elem2 != NULL, "got %p\n", elem2);
10039
10040     EXPECT_REF(elem2, 1);
10041     V_VT(&v) = VT_NULL;
10042     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
10043     ok(hr == S_OK, "got 0x%08x\n", hr);
10044     EXPECT_REF(elem2, 1);
10045
10046     p = NULL;
10047     hr = IXMLDOMElement_get_xml(elem2, &p);
10048     ok(hr == S_OK, "got 0x%08x\n", hr);
10049     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
10050     SysFreeString(p);
10051
10052     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
10053     ok(hr == S_OK, "got 0x%08x\n", hr);
10054
10055     p = NULL;
10056     hr = IXMLDOMElement_get_xml(elem2, &p);
10057     ok(hr == S_OK, "got 0x%08x\n", hr);
10058     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
10059     SysFreeString(p);
10060
10061     IXMLDOMElement_Release(elem1);
10062     IXMLDOMElement_Release(elem2);
10063     IXMLDOMDocument_Release(doc);
10064 }
10065
10066 static void test_appendChild(void)
10067 {
10068     IXMLDOMDocument *doc, *doc2;
10069     IXMLDOMElement *elem, *elem2;
10070     HRESULT hr;
10071
10072     doc = create_document(&IID_IXMLDOMDocument);
10073     doc2 = create_document(&IID_IXMLDOMDocument);
10074
10075     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
10076     ok(hr == S_OK, "got 0x%08x\n", hr);
10077
10078     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
10079     ok(hr == S_OK, "got 0x%08x\n", hr);
10080
10081     EXPECT_REF(doc, 1);
10082     todo_wine EXPECT_REF(elem, 2);
10083     EXPECT_REF(doc2, 1);
10084     todo_wine EXPECT_REF(elem2, 2);
10085     EXPECT_NO_CHILDREN(doc);
10086     EXPECT_NO_CHILDREN(doc2);
10087
10088     /* append from another document */
10089     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
10090     ok(hr == S_OK, "got 0x%08x\n", hr);
10091
10092     EXPECT_REF(doc, 1);
10093     todo_wine EXPECT_REF(elem, 2);
10094     EXPECT_REF(doc2, 1);
10095     todo_wine EXPECT_REF(elem2, 2);
10096     EXPECT_NO_CHILDREN(doc);
10097     EXPECT_CHILDREN(doc2);
10098
10099     IXMLDOMElement_Release(elem);
10100     IXMLDOMElement_Release(elem2);
10101     IXMLDOMDocument_Release(doc);
10102     IXMLDOMDocument_Release(doc2);
10103 }
10104
10105 static void test_get_doctype(void)
10106 {
10107     IXMLDOMDocumentType *doctype;
10108     IXMLDOMDocument *doc;
10109     HRESULT hr;
10110
10111     doc = create_document(&IID_IXMLDOMDocument);
10112
10113     hr = IXMLDOMDocument_get_doctype(doc, NULL);
10114     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10115
10116     doctype = (void*)0xdeadbeef;
10117     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
10118     ok(hr == S_FALSE, "got 0x%08x\n", hr);
10119     ok(doctype == NULL, "got %p\n", doctype);
10120
10121     IXMLDOMDocument_Release(doc);
10122 }
10123
10124 static void test_get_tagName(void)
10125 {
10126     IXMLDOMDocument *doc;
10127     IXMLDOMElement *elem, *elem2;
10128     HRESULT hr;
10129     BSTR str;
10130
10131     doc = create_document(&IID_IXMLDOMDocument);
10132
10133     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
10134     ok(hr == S_OK, "got 0x%08x\n", hr);
10135
10136     hr = IXMLDOMElement_get_tagName(elem, NULL);
10137     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10138
10139     str = NULL;
10140     hr = IXMLDOMElement_get_tagName(elem, &str);
10141     ok(hr == S_OK, "got 0x%08x\n", hr);
10142     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
10143     SysFreeString(str);
10144
10145     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
10146     ok(hr == S_OK, "got 0x%08x\n", hr);
10147
10148     str = NULL;
10149     hr = IXMLDOMElement_get_tagName(elem2, &str);
10150     ok(hr == S_OK, "got 0x%08x\n", hr);
10151     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
10152     SysFreeString(str);
10153
10154     IXMLDOMElement_Release(elem);
10155     IXMLDOMElement_Release(elem2);
10156     IXMLDOMDocument_Release(doc);
10157     free_bstrs();
10158 }
10159
10160 typedef struct {
10161     DOMNodeType type;
10162     const char *name;
10163     VARTYPE vt;
10164     HRESULT hr;
10165 } node_type_t;
10166
10167 static const node_type_t get_datatype[] = {
10168     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
10169     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
10170     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
10171     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
10172     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
10173     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
10174     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
10175     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
10176     { 0 }
10177 };
10178
10179 static void test_get_dataType(void)
10180 {
10181     const node_type_t *entry = get_datatype;
10182     IXMLDOMDocument *doc;
10183
10184     doc = create_document(&IID_IXMLDOMDocument);
10185
10186     while (entry->type)
10187     {
10188         IXMLDOMNode *node = NULL;
10189         VARIANT var, type;
10190         HRESULT hr;
10191
10192         V_VT(&var) = VT_I4;
10193         V_I4(&var) = entry->type;
10194         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
10195         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10196
10197         hr = IXMLDOMNode_get_dataType(node, NULL);
10198         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10199
10200         VariantInit(&type);
10201         hr = IXMLDOMNode_get_dataType(node, &type);
10202         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10203             hr, entry->hr, entry->type);
10204         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
10205             V_VT(&type), entry->vt, entry->type);
10206         VariantClear(&type);
10207
10208         IXMLDOMNode_Release(node);
10209
10210         entry++;
10211     }
10212
10213     IXMLDOMDocument_Release(doc);
10214     free_bstrs();
10215 }
10216
10217 typedef struct _get_node_typestring_t {
10218     DOMNodeType type;
10219     const char *string;
10220 } get_node_typestring_t;
10221
10222 static const get_node_typestring_t get_node_typestring[] = {
10223     { NODE_ELEMENT,                "element"               },
10224     { NODE_ATTRIBUTE,              "attribute"             },
10225     { NODE_TEXT,                   "text"                  },
10226     { NODE_CDATA_SECTION ,         "cdatasection"          },
10227     { NODE_ENTITY_REFERENCE,       "entityreference"       },
10228     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
10229     { NODE_COMMENT,                "comment"               },
10230     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
10231     { 0 }
10232 };
10233
10234 static void test_get_nodeTypeString(void)
10235 {
10236     const get_node_typestring_t *entry = get_node_typestring;
10237     IXMLDOMDocument *doc;
10238     HRESULT hr;
10239     BSTR str;
10240
10241     doc = create_document(&IID_IXMLDOMDocument);
10242
10243     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
10244     ok(hr == S_OK, "got 0x%08x\n", hr);
10245     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
10246     SysFreeString(str);
10247
10248     while (entry->type)
10249     {
10250         IXMLDOMNode *node = NULL;
10251         VARIANT var;
10252
10253         V_VT(&var) = VT_I4;
10254         V_I4(&var) = entry->type;
10255         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10256         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10257
10258         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
10259         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10260
10261         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
10262         ok(hr == S_OK, "got 0x%08x\n", hr);
10263         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
10264             wine_dbgstr_w(str), entry->string, entry->type);
10265         SysFreeString(str);
10266         IXMLDOMNode_Release(node);
10267
10268         entry++;
10269     }
10270
10271     IXMLDOMDocument_Release(doc);
10272     free_bstrs();
10273 }
10274
10275 typedef struct _get_attributes_t {
10276     DOMNodeType type;
10277     HRESULT hr;
10278 } get_attributes_t;
10279
10280 static const get_attributes_t get_attributes[] = {
10281     { NODE_ATTRIBUTE,              S_FALSE },
10282     { NODE_TEXT,                   S_FALSE },
10283     { NODE_CDATA_SECTION ,         S_FALSE },
10284     { NODE_ENTITY_REFERENCE,       S_FALSE },
10285     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
10286     { NODE_COMMENT,                S_FALSE },
10287     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
10288     { 0 }
10289 };
10290
10291 static void test_get_attributes(void)
10292 {
10293     const get_attributes_t *entry = get_attributes;
10294     IXMLDOMNamedNodeMap *map;
10295     IXMLDOMDocument *doc;
10296     IXMLDOMNode *node, *node2;
10297     VARIANT_BOOL b;
10298     HRESULT hr;
10299     BSTR str;
10300     LONG length;
10301
10302     doc = create_document(&IID_IXMLDOMDocument);
10303
10304     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
10305     ok(hr == S_OK, "got %08x\n", hr);
10306
10307     hr = IXMLDOMDocument_get_attributes(doc, NULL);
10308     ok(hr == E_INVALIDARG, "got %08x\n", hr);
10309
10310     map = (void*)0xdeadbeef;
10311     hr = IXMLDOMDocument_get_attributes(doc, &map);
10312     ok(hr == S_FALSE, "got %08x\n", hr);
10313     ok(map == NULL, "got %p\n", map);
10314
10315     /* first child is <?xml ?> */
10316     hr = IXMLDOMDocument_get_firstChild(doc, &node);
10317     ok(hr == S_OK, "got %08x\n", hr);
10318
10319     hr = IXMLDOMNode_get_attributes(node, &map);
10320     ok(hr == S_OK, "got %08x\n", hr);
10321
10322     length = -1;
10323     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10324     EXPECT_HR(hr, S_OK);
10325     todo_wine ok(length == 1, "got %d\n", length);
10326
10327     if (hr == S_OK && length == 1)
10328     {
10329         IXMLDOMAttribute *attr;
10330         DOMNodeType type;
10331         VARIANT v;
10332
10333         node2 = NULL;
10334         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10335         EXPECT_HR(hr, S_OK);
10336         ok(node != NULL, "got %p\n", node2);
10337
10338         hr = IXMLDOMNode_get_nodeName(node2, &str);
10339         EXPECT_HR(hr, S_OK);
10340         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
10341         SysFreeString(str);
10342
10343         length = -1;
10344         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10345         EXPECT_HR(hr, S_OK);
10346         ok(length == 1, "got %d\n", length);
10347
10348         type = -1;
10349         hr = IXMLDOMNode_get_nodeType(node2, &type);
10350         EXPECT_HR(hr, S_OK);
10351         ok(type == NODE_ATTRIBUTE, "got %d\n", type);
10352
10353         hr = IXMLDOMNode_get_xml(node, &str);
10354         EXPECT_HR(hr, S_OK);
10355         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
10356         SysFreeString(str);
10357
10358         hr = IXMLDOMNode_get_text(node, &str);
10359         EXPECT_HR(hr, S_OK);
10360         ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
10361         SysFreeString(str);
10362
10363         hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
10364         EXPECT_HR(hr, S_OK);
10365
10366         length = -1;
10367         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10368         EXPECT_HR(hr, S_OK);
10369         ok(length == 0, "got %d\n", length);
10370
10371         hr = IXMLDOMNode_get_xml(node, &str);
10372         EXPECT_HR(hr, S_OK);
10373         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
10374         SysFreeString(str);
10375
10376         hr = IXMLDOMNode_get_text(node, &str);
10377         EXPECT_HR(hr, S_OK);
10378         ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
10379         SysFreeString(str);
10380
10381         IXMLDOMNamedNodeMap_Release(map);
10382
10383         hr = IXMLDOMNode_get_attributes(node, &map);
10384         ok(hr == S_OK, "got %08x\n", hr);
10385
10386         length = -1;
10387         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10388         EXPECT_HR(hr, S_OK);
10389         ok(length == 0, "got %d\n", length);
10390
10391         hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
10392         EXPECT_HR(hr, S_OK);
10393
10394         V_VT(&v) = VT_BSTR;
10395         V_BSTR(&v) = _bstr_("UTF-8");
10396         hr = IXMLDOMAttribute_put_nodeValue(attr, v);
10397         EXPECT_HR(hr, S_OK);
10398
10399         EXPECT_REF(attr, 2);
10400         hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
10401         EXPECT_HR(hr, S_OK);
10402         EXPECT_REF(attr, 2);
10403
10404         hr = IXMLDOMNode_get_attributes(node, &map);
10405         ok(hr == S_OK, "got %08x\n", hr);
10406
10407         length = -1;
10408         hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10409         EXPECT_HR(hr, S_OK);
10410         ok(length == 1, "got %d\n", length);
10411
10412         hr = IXMLDOMNode_get_xml(node, &str);
10413         EXPECT_HR(hr, S_OK);
10414         ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
10415         SysFreeString(str);
10416
10417         hr = IXMLDOMNode_get_text(node, &str);
10418         EXPECT_HR(hr, S_OK);
10419         ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
10420         SysFreeString(str);
10421
10422         IXMLDOMNamedNodeMap_Release(map);
10423         IXMLDOMNode_Release(node2);
10424     }
10425
10426     IXMLDOMNode_Release(node);
10427
10428     /* last child is element */
10429     EXPECT_REF(doc, 1);
10430     hr = IXMLDOMDocument_get_lastChild(doc, &node);
10431     ok(hr == S_OK, "got %08x\n", hr);
10432     EXPECT_REF(doc, 1);
10433
10434     EXPECT_REF(node, 1);
10435     hr = IXMLDOMNode_get_attributes(node, &map);
10436     ok(hr == S_OK, "got %08x\n", hr);
10437     EXPECT_REF(node, 1);
10438     EXPECT_REF(doc, 1);
10439
10440     EXPECT_REF(map, 1);
10441     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10442     ok(hr == S_OK, "got %08x\n", hr);
10443     EXPECT_REF(node, 1);
10444     EXPECT_REF(node2, 1);
10445     EXPECT_REF(map, 1);
10446     EXPECT_REF(doc, 1);
10447     IXMLDOMNode_Release(node2);
10448
10449     /* release node before map release, map still works */
10450     IXMLDOMNode_Release(node);
10451
10452     length = 0;
10453     hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10454     ok(hr == S_OK, "got %08x\n", hr);
10455     ok(length == 1, "got %d\n", length);
10456
10457     node2 = NULL;
10458     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10459     ok(hr == S_OK, "got %08x\n", hr);
10460     EXPECT_REF(node2, 1);
10461     IXMLDOMNode_Release(node2);
10462
10463     IXMLDOMNamedNodeMap_Release(map);
10464
10465     while (entry->type)
10466     {
10467         VARIANT var;
10468
10469         node = NULL;
10470
10471         V_VT(&var) = VT_I4;
10472         V_I4(&var) = entry->type;
10473         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10474         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10475
10476         hr = IXMLDOMNode_get_attributes(node, NULL);
10477         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
10478
10479         map = (void*)0xdeadbeef;
10480         hr = IXMLDOMNode_get_attributes(node, &map);
10481         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
10482             hr, entry->hr, entry->type);
10483         ok(map == NULL, "got %p\n", map);
10484
10485         IXMLDOMNode_Release(node);
10486
10487         entry++;
10488     }
10489
10490     IXMLDOMDocument_Release(doc);
10491     free_bstrs();
10492 }
10493
10494 static void test_selection(void)
10495 {
10496     IXMLDOMSelection *selection, *selection2;
10497     IEnumVARIANT *enum1, *enum2, *enum3;
10498     IXMLDOMNodeList *list;
10499     IUnknown *unk1, *unk2;
10500     IXMLDOMDocument *doc;
10501     IDispatchEx *dispex;
10502     IXMLDOMNode *node;
10503     IDispatch *disp;
10504     VARIANT_BOOL b;
10505     HRESULT hr;
10506     DISPID did;
10507     VARIANT v;
10508     BSTR name;
10509     ULONG ret;
10510     LONG len;
10511
10512     doc = create_document(&IID_IXMLDOMDocument);
10513
10514     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10515     EXPECT_HR(hr, S_OK);
10516
10517     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10518     EXPECT_HR(hr, S_OK);
10519
10520     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10521     EXPECT_HR(hr, S_OK);
10522     IXMLDOMSelection_Release(selection);
10523
10524     /* collection disp id */
10525     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10526     EXPECT_HR(hr, S_OK);
10527     did = 0;
10528     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10529     EXPECT_HR(hr, S_OK);
10530     ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
10531     len = 0;
10532     hr = IXMLDOMSelection_get_length(selection, &len);
10533     EXPECT_HR(hr, S_OK);
10534     ok(len == 1, "got %d\n", len);
10535     hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10536     EXPECT_HR(hr, S_OK);
10537     ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
10538     IDispatchEx_Release(dispex);
10539
10540     /* IEnumVARIANT tests */
10541     enum1 = NULL;
10542     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10543     EXPECT_HR(hr, S_OK);
10544     ok(enum1 != NULL, "got %p\n", enum1);
10545     EXPECT_REF(enum1, 2);
10546
10547     EXPECT_REF(selection, 1);
10548     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1);
10549     EXPECT_HR(hr, S_OK);
10550     EXPECT_REF(selection, 2);
10551     EXPECT_REF(enum1, 2);
10552
10553     /* enumerator and selection object return same IUnknown* */
10554     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
10555     EXPECT_HR(hr, S_OK);
10556     EXPECT_REF(selection, 3);
10557     EXPECT_REF(enum1, 2);
10558     ok(unk2 == unk1, "got %p, %p\n", unk1, unk2);
10559     IUnknown_Release(unk2);
10560
10561     EXPECT_REF(selection, 2);
10562     IEnumVARIANT_AddRef(enum1);
10563     EXPECT_REF(selection, 2);
10564     IEnumVARIANT_Release(enum1);
10565
10566     enum3 = NULL;
10567     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10568     EXPECT_HR(hr, S_OK);
10569     ok(enum3 != NULL, "got %p\n", enum3);
10570     ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10571     EXPECT_REF(enum1, 3);
10572     IEnumVARIANT_Release(enum3);
10573
10574     EXPECT_REF(selection, 2);
10575     EXPECT_REF(enum1, 2);
10576
10577     enum2 = NULL;
10578     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10579     EXPECT_HR(hr, S_OK);
10580     ok(enum2 != NULL, "got %p\n", enum2);
10581
10582     EXPECT_REF(selection, 3);
10583     EXPECT_REF(enum1, 2);
10584     EXPECT_REF(enum2, 1);
10585
10586     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10587
10588     hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
10589     EXPECT_HR(hr, S_OK);
10590     EXPECT_REF(selection, 3);
10591     EXPECT_REF(enum2, 2);
10592     ok(unk2 != unk1, "got %p, %p\n", unk1, unk2);
10593     IUnknown_Release(unk2);
10594     IUnknown_Release(unk1);
10595
10596     selection2 = NULL;
10597     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10598     EXPECT_HR(hr, S_OK);
10599     ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10600     EXPECT_REF(selection, 3);
10601     EXPECT_REF(enum1, 2);
10602
10603     IXMLDOMSelection_Release(selection2);
10604
10605     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10606     EXPECT_HR(hr, S_OK);
10607     EXPECT_REF(selection, 3);
10608     IDispatch_Release(disp);
10609
10610     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10611     EXPECT_HR(hr, S_OK);
10612     ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10613     EXPECT_REF(selection, 2);
10614     EXPECT_REF(enum1, 3);
10615
10616     IEnumVARIANT_Release(enum1);
10617     IEnumVARIANT_Release(enum2);
10618
10619     enum1 = NULL;
10620     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10621     EXPECT_HR(hr, S_OK);
10622     ok(enum1 != NULL, "got %p\n", enum1);
10623     EXPECT_REF(enum1, 1);
10624     EXPECT_REF(selection, 2);
10625
10626     enum2 = NULL;
10627     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10628     EXPECT_HR(hr, S_OK);
10629     ok(enum2 != NULL, "got %p\n", enum2);
10630     EXPECT_REF(enum2, 1);
10631     EXPECT_REF(selection, 3);
10632
10633     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10634
10635     IEnumVARIANT_AddRef(enum1);
10636     EXPECT_REF(selection, 3);
10637     EXPECT_REF(enum1, 2);
10638     EXPECT_REF(enum2, 1);
10639     IEnumVARIANT_Release(enum1);
10640
10641     IEnumVARIANT_Release(enum1);
10642     IEnumVARIANT_Release(enum2);
10643
10644     EXPECT_REF(selection, 1);
10645
10646     IXMLDOMNodeList_Release(list);
10647
10648     hr = IXMLDOMDocument_get_childNodes(doc, &list);
10649     EXPECT_HR(hr, S_OK);
10650
10651     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10652     EXPECT_HR(hr, E_NOINTERFACE);
10653
10654     IXMLDOMNodeList_Release(list);
10655
10656     /* test if IEnumVARIANT touches selection context */
10657     hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
10658     EXPECT_HR(hr, S_OK);
10659
10660     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10661     EXPECT_HR(hr, S_OK);
10662
10663     hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10664     EXPECT_HR(hr, S_OK);
10665
10666     len = 0;
10667     hr = IXMLDOMSelection_get_length(selection, &len);
10668     EXPECT_HR(hr, S_OK);
10669     ok(len == 4, "got %d\n", len);
10670
10671     enum1 = NULL;
10672     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10673     EXPECT_HR(hr, S_OK);
10674
10675     /* no-op if zero count */
10676     V_VT(&v) = VT_I2;
10677     hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10678     EXPECT_HR(hr, S_OK);
10679     ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10680
10681     /* positive count, null array pointer */
10682     hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10683     EXPECT_HR(hr, E_INVALIDARG);
10684
10685     ret = 1;
10686     hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10687     EXPECT_HR(hr, E_INVALIDARG);
10688     ok(ret == 0, "got %d\n", ret);
10689
10690     V_VT(&v) = VT_I2;
10691     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10692     EXPECT_HR(hr, S_OK);
10693     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10694
10695     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10696     EXPECT_HR(hr, S_OK);
10697     hr = IXMLDOMNode_get_nodeName(node, &name);
10698     EXPECT_HR(hr, S_OK);
10699     ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10700     SysFreeString(name);
10701     IXMLDOMNode_Release(node);
10702     VariantClear(&v);
10703
10704     /* list cursor is updated */
10705     hr = IXMLDOMSelection_nextNode(selection, &node);
10706     EXPECT_HR(hr, S_OK);
10707     hr = IXMLDOMNode_get_nodeName(node, &name);
10708     EXPECT_HR(hr, S_OK);
10709     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10710     IXMLDOMNode_Release(node);
10711
10712     V_VT(&v) = VT_I2;
10713     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10714     EXPECT_HR(hr, S_OK);
10715     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10716     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10717     EXPECT_HR(hr, S_OK);
10718     hr = IXMLDOMNode_get_nodeName(node, &name);
10719     EXPECT_HR(hr, S_OK);
10720     ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10721     SysFreeString(name);
10722     IXMLDOMNode_Release(node);
10723     VariantClear(&v);
10724     IEnumVARIANT_Release(enum1);
10725
10726     hr = IXMLDOMSelection_nextNode(selection, &node);
10727     EXPECT_HR(hr, S_OK);
10728     hr = IXMLDOMNode_get_nodeName(node, &name);
10729     EXPECT_HR(hr, S_OK);
10730     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10731     IXMLDOMNode_Release(node);
10732
10733     IXMLDOMSelection_Release(selection);
10734     IXMLDOMNodeList_Release(list);
10735     IXMLDOMDocument_Release(doc);
10736
10737     free_bstrs();
10738 }
10739
10740 static void test_load(void)
10741 {
10742     IXMLDOMDocument *doc;
10743     IXMLDOMNodeList *list;
10744     VARIANT_BOOL b;
10745     HANDLE hfile;
10746     VARIANT src;
10747     HRESULT hr;
10748     BOOL ret;
10749     BSTR path, bstr1, bstr2;
10750     DWORD written;
10751     void* ptr;
10752
10753     /* prepare a file */
10754     hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10755     ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
10756     if(hfile == INVALID_HANDLE_VALUE) return;
10757
10758     ret = WriteFile(hfile, win1252xml, strlen(win1252xml), &written, NULL);
10759     ok(ret, "WriteFile failed\n");
10760
10761     CloseHandle(hfile);
10762
10763     doc = create_document(&IID_IXMLDOMDocument);
10764
10765     /* null pointer as input */
10766     V_VT(&src) = VT_UNKNOWN;
10767     V_UNKNOWN(&src) = NULL;
10768     hr = IXMLDOMDocument_load(doc, src, &b);
10769     EXPECT_HR(hr, E_INVALIDARG);
10770     ok(b == VARIANT_FALSE, "got %d\n", b);
10771
10772     path = _bstr_("test.xml");
10773
10774     /* load from path: VT_BSTR */
10775     V_VT(&src) = VT_BSTR;
10776     V_BSTR(&src) = path;
10777     hr = IXMLDOMDocument_load(doc, src, &b);
10778     EXPECT_HR(hr, S_OK);
10779     ok(b == VARIANT_TRUE, "got %d\n", b);
10780
10781     /* load from a path: VT_BSTR|VT_BYREF */
10782     V_VT(&src) = VT_BSTR | VT_BYREF;
10783     V_BSTRREF(&src) = &path;
10784     hr = IXMLDOMDocument_load(doc, src, &b);
10785     EXPECT_HR(hr, S_OK);
10786     ok(b == VARIANT_TRUE, "got %d\n", b);
10787
10788     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10789     V_VT(&src) = VT_BSTR | VT_BYREF;
10790     V_BSTRREF(&src) = NULL;
10791     hr = IXMLDOMDocument_load(doc, src, &b);
10792     EXPECT_HR(hr, E_INVALIDARG);
10793     ok(b == VARIANT_FALSE, "got %d\n", b);
10794
10795     IXMLDOMDocument_Release(doc);
10796
10797     DeleteFileA("test.xml");
10798
10799     doc = create_document(&IID_IXMLDOMDocument);
10800
10801     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10802     EXPECT_HR(hr, S_OK);
10803     ok(b == VARIANT_TRUE, "got %d\n", b);
10804
10805     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10806     EXPECT_HR(hr, S_OK);
10807     bstr1 = _bstr_(list_to_string(list));
10808
10809     hr = IXMLDOMNodeList_reset(list);
10810     EXPECT_HR(hr, S_OK);
10811
10812     IXMLDOMDocument_Release(doc);
10813
10814     doc = create_document(&IID_IXMLDOMDocument);
10815
10816     VariantInit(&src);
10817     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10818     V_VT(&src) = VT_ARRAY|VT_UI1;
10819     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10820     ptr = NULL;
10821     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10822     EXPECT_HR(hr, S_OK);
10823     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10824
10825     memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10826     hr = SafeArrayUnlock(V_ARRAY(&src));
10827     EXPECT_HR(hr, S_OK);
10828
10829     hr = IXMLDOMDocument_load(doc, src, &b);
10830     EXPECT_HR(hr, S_OK);
10831     ok(b == VARIANT_TRUE, "got %d\n", b);
10832
10833     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10834     EXPECT_HR(hr, S_OK);
10835     bstr2 = _bstr_(list_to_string(list));
10836
10837     hr = IXMLDOMNodeList_reset(list);
10838     EXPECT_HR(hr, S_OK);
10839
10840     ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10841        wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10842
10843     IXMLDOMDocument_Release(doc);
10844     IXMLDOMNodeList_Release(list);
10845     VariantClear(&src);
10846
10847     /* UTF-16 isn't accepted */
10848     doc = create_document(&IID_IXMLDOMDocument);
10849
10850     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10851     V_VT(&src) = VT_ARRAY|VT_UI1;
10852     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10853     ptr = NULL;
10854     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10855     EXPECT_HR(hr, S_OK);
10856     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10857
10858     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10859     hr = SafeArrayUnlock(V_ARRAY(&src));
10860     EXPECT_HR(hr, S_OK);
10861
10862     hr = IXMLDOMDocument_load(doc, src, &b);
10863     todo_wine EXPECT_HR(hr, S_FALSE);
10864     todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10865
10866     VariantClear(&src);
10867
10868     /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10869     V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10870     V_VT(&src) = VT_ARRAY|VT_UI2;
10871     ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10872     ptr = NULL;
10873     hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10874     EXPECT_HR(hr, S_OK);
10875     ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10876
10877     memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10878     hr = SafeArrayUnlock(V_ARRAY(&src));
10879     EXPECT_HR(hr, S_OK);
10880
10881     hr = IXMLDOMDocument_load(doc, src, &b);
10882     todo_wine EXPECT_HR(hr, E_INVALIDARG);
10883     ok(b == VARIANT_FALSE, "got %d\n", b);
10884
10885     VariantClear(&src);
10886     IXMLDOMDocument_Release(doc);
10887
10888     free_bstrs();
10889 }
10890
10891 static void test_domobj_dispex(IUnknown *obj)
10892 {
10893     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10894     IDispatchEx *dispex;
10895     IUnknown *unk;
10896     DWORD props;
10897     UINT ticnt;
10898     HRESULT hr;
10899     BSTR name;
10900
10901     hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10902     EXPECT_HR(hr, S_OK);
10903     if (FAILED(hr)) return;
10904
10905     ticnt = 0;
10906     hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10907     EXPECT_HR(hr, S_OK);
10908     ok(ticnt == 1, "ticnt=%u\n", ticnt);
10909
10910     name = SysAllocString(szstar);
10911     hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10912     EXPECT_HR(hr, E_NOTIMPL);
10913     SysFreeString(name);
10914
10915     hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10916     EXPECT_HR(hr, E_NOTIMPL);
10917
10918     props = 0;
10919     hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10920     EXPECT_HR(hr, E_NOTIMPL);
10921     ok(props == 0, "expected 0 got %d\n", props);
10922
10923     hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10924     EXPECT_HR(hr, E_NOTIMPL);
10925     if (SUCCEEDED(hr)) SysFreeString(name);
10926
10927     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10928     EXPECT_HR(hr, E_NOTIMPL);
10929
10930     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10931     EXPECT_HR(hr, E_NOTIMPL);
10932     if (hr == S_OK && unk) IUnknown_Release(unk);
10933
10934     IDispatchEx_Release(dispex);
10935 }
10936
10937 static void test_mxnamespacemanager(void)
10938 {
10939     static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10940     IMXNamespacePrefixes *prefixes;
10941     IVBMXNamespaceManager *mgr2;
10942     IMXNamespaceManager *nsmgr;
10943     IUnknown *unk1, *unk2;
10944     WCHAR buffW[250];
10945     IDispatch *disp;
10946     IUnknown *unk;
10947     HRESULT hr;
10948     INT len;
10949
10950     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10951         &IID_IMXNamespaceManager, (void**)&nsmgr);
10952     EXPECT_HR(hr, S_OK);
10953
10954     /* IMXNamespaceManager inherits from IUnknown */
10955     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10956     EXPECT_HR(hr, S_OK);
10957     IDispatch_Release(disp);
10958
10959     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10960     EXPECT_HR(hr, S_OK);
10961
10962     EXPECT_REF(nsmgr, 2);
10963     EXPECT_REF(mgr2, 2);
10964     prefixes = NULL;
10965     hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
10966     if (hr == S_OK)
10967     {
10968         ok(prefixes != NULL, "got %p\n", prefixes);
10969         EXPECT_REF(nsmgr, 2);
10970         EXPECT_REF(mgr2, 2);
10971         EXPECT_REF(prefixes, 1);
10972
10973         IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1);
10974         IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2);
10975
10976         EXPECT_REF(mgr2, 3);
10977         EXPECT_REF(prefixes, 2);
10978
10979         IUnknown_Release(unk1);
10980         IUnknown_Release(unk2);
10981         IMXNamespacePrefixes_Release(prefixes);
10982     }
10983     IVBMXNamespaceManager_Release(mgr2);
10984
10985     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10986     EXPECT_HR(hr, S_OK);
10987
10988     /* prefix already added */
10989     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10990     EXPECT_HR(hr, S_FALSE);
10991
10992     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10993     EXPECT_HR(hr, E_INVALIDARG);
10994
10995     /* "xml" and "xmlns" are not allowed here */
10996     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10997     EXPECT_HR(hr, E_INVALIDARG);
10998
10999     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
11000     EXPECT_HR(hr, E_INVALIDARG);
11001 todo_wine {
11002     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
11003     EXPECT_HR(hr, E_FAIL);
11004 }
11005     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
11006     EXPECT_HR(hr, E_POINTER);
11007
11008     len = -1;
11009     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
11010     EXPECT_HR(hr, S_OK);
11011     ok(len == 3, "got %d\n", len);
11012
11013     len = -1;
11014     buffW[0] = 0x1;
11015     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11016     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
11017     ok(len == -1, "got %d\n", len);
11018     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11019
11020     len = 10;
11021     buffW[0] = 0x1;
11022     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11023     EXPECT_HR(hr, S_OK);
11024     ok(len == 3, "got %d\n", len);
11025     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
11026
11027     /* getURI */
11028     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
11029     EXPECT_HR(hr, E_INVALIDARG);
11030
11031     len = -1;
11032     hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
11033     EXPECT_HR(hr, E_INVALIDARG);
11034     ok(len == -1, "got %d\n", len);
11035
11036     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
11037     EXPECT_HR(hr, E_POINTER);
11038
11039     len = -1;
11040     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
11041     EXPECT_HR(hr, S_OK);
11042     /* length of "xml" uri is constant */
11043     ok(len == strlen(xmluriA), "got %d\n", len);
11044
11045     len = 100;
11046     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
11047     EXPECT_HR(hr, S_OK);
11048     ok(len == strlen(xmluriA), "got %d\n", len);
11049     ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
11050
11051     len = strlen(xmluriA)-1;
11052     buffW[0] = 0x1;
11053     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
11054     EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
11055     ok(len == strlen(xmluriA)-1, "got %d\n", len);
11056     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11057
11058     /* prefix xml1 not defined */
11059     len = -1;
11060     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
11061     EXPECT_HR(hr, S_FALSE);
11062     ok(len == 0, "got %d\n", len);
11063
11064     len = 100;
11065     buffW[0] = 0x1;
11066     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
11067     EXPECT_HR(hr, S_FALSE);
11068     ok(buffW[0] == 0, "got %x\n", buffW[0]);
11069     ok(len == 0, "got %d\n", len);
11070
11071     /* IDispatchEx tests */
11072     hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
11073     EXPECT_HR(hr, S_OK);
11074     test_domobj_dispex(unk);
11075     IUnknown_Release(unk);
11076
11077     IMXNamespaceManager_Release(nsmgr);
11078
11079     /* ::getPrefix() */
11080     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11081         &IID_IMXNamespaceManager, (void**)&nsmgr);
11082     EXPECT_HR(hr, S_OK);
11083
11084     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
11085     EXPECT_HR(hr, E_INVALIDARG);
11086
11087     len = -1;
11088     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
11089     EXPECT_HR(hr, E_INVALIDARG);
11090     ok(len == -1, "got %d\n", len);
11091
11092     len = 100;
11093     buffW[0] = 0x1;
11094     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
11095     EXPECT_HR(hr, E_FAIL);
11096     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11097     ok(len == 100, "got %d\n", len);
11098
11099     len = 0;
11100     buffW[0] = 0x1;
11101     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
11102     EXPECT_HR(hr, E_FAIL);
11103     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11104     ok(len == 0, "got %d\n", len);
11105
11106     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11107     EXPECT_HR(hr, S_OK);
11108
11109     len = 100;
11110     buffW[0] = 0x1;
11111     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11112     EXPECT_HR(hr, S_OK);
11113     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11114     ok(len == 3, "got %d\n", len);
11115
11116     len = 100;
11117     buffW[0] = 0x1;
11118     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
11119     EXPECT_HR(hr, S_OK);
11120     ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
11121     ok(len == 3, "got %d\n", len);
11122
11123     /* with null buffer it's possible to get required length */
11124     len = 100;
11125     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
11126     EXPECT_HR(hr, S_OK);
11127     ok(len == 3, "got %d\n", len);
11128
11129     len = 0;
11130     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
11131     EXPECT_HR(hr, S_OK);
11132     ok(len == 3, "got %d\n", len);
11133
11134     len = 100;
11135     buffW[0] = 0x1;
11136     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
11137     EXPECT_HR(hr, E_FAIL);
11138     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11139     ok(len == 100, "got %d\n", len);
11140
11141     len = 100;
11142     buffW[0] = 0x1;
11143     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
11144     EXPECT_HR(hr, E_FAIL);
11145     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11146     ok(len == 100, "got %d\n", len);
11147
11148     len = 100;
11149     buffW[0] = 0x1;
11150     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
11151     EXPECT_HR(hr, E_INVALIDARG);
11152     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11153     ok(len == 100, "got %d\n", len);
11154
11155     len = 100;
11156     buffW[0] = 0x1;
11157     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11158     EXPECT_HR(hr, E_INVALIDARG);
11159     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11160     ok(len == 100, "got %d\n", len);
11161
11162     len = 100;
11163     buffW[0] = 0x1;
11164     hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
11165     EXPECT_HR(hr, E_INVALIDARG);
11166     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11167     ok(len == 100, "got %d\n", len);
11168
11169     len = 100;
11170     buffW[0] = 0x1;
11171     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
11172     EXPECT_HR(hr, E_FAIL);
11173     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11174     ok(len == 100, "got %d\n", len);
11175
11176     len = 100;
11177     buffW[0] = 0x1;
11178     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11179     EXPECT_HR(hr, E_INVALIDARG);
11180     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11181     ok(len == 100, "got %d\n", len);
11182
11183     /* declare another one, indices are shifted */
11184     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
11185     EXPECT_HR(hr, S_OK);
11186
11187     len = 100;
11188     buffW[0] = 0x1;
11189     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11190     EXPECT_HR(hr, S_OK);
11191     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11192     ok(len == 3, "got %d\n", len);
11193
11194     len = 100;
11195     buffW[0] = 0x1;
11196     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11197     EXPECT_HR(hr, S_OK);
11198     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
11199     ok(len == 3, "got %d\n", len);
11200
11201     len = 100;
11202     buffW[0] = 0x1;
11203     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
11204     EXPECT_HR(hr, E_FAIL);
11205     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11206     ok(len == 100, "got %d\n", len);
11207
11208     len = 100;
11209     buffW[0] = 0x1;
11210     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11211     EXPECT_HR(hr, E_INVALIDARG);
11212     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11213     ok(len == 100, "got %d\n", len);
11214
11215     IMXNamespaceManager_Release(nsmgr);
11216
11217     /* push/pop tests */
11218     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11219         &IID_IMXNamespaceManager, (void**)&nsmgr);
11220     EXPECT_HR(hr, S_OK);
11221
11222     /* pop with empty stack */
11223     hr = IMXNamespaceManager_popContext(nsmgr);
11224     EXPECT_HR(hr, E_FAIL);
11225
11226     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11227     EXPECT_HR(hr, S_OK);
11228
11229     len = 100;
11230     buffW[0] = 0x1;
11231     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11232     EXPECT_HR(hr, S_OK);
11233     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11234     ok(len == 3, "got %d\n", len);
11235
11236     hr = IMXNamespaceManager_pushContext(nsmgr);
11237     EXPECT_HR(hr, S_OK);
11238
11239     len = 100;
11240     buffW[0] = 0x1;
11241     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11242     EXPECT_HR(hr, S_OK);
11243     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11244     ok(len == 3, "got %d\n", len);
11245
11246     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
11247     EXPECT_HR(hr, S_OK);
11248
11249     len = 100;
11250     buffW[0] = 0x1;
11251     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11252     EXPECT_HR(hr, S_OK);
11253     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
11254     ok(len == 3, "got %d\n", len);
11255
11256     hr = IMXNamespaceManager_pushContext(nsmgr);
11257     EXPECT_HR(hr, S_OK);
11258     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
11259     EXPECT_HR(hr, S_OK);
11260
11261     len = 100;
11262     buffW[0] = 0x1;
11263     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11264     EXPECT_HR(hr, S_OK);
11265     ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
11266     ok(len == 3, "got %d\n", len);
11267
11268     len = 100;
11269     buffW[0] = 0x1;
11270     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11271     EXPECT_HR(hr, S_OK);
11272     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11273     ok(len == 3, "got %d\n", len);
11274
11275     hr = IMXNamespaceManager_popContext(nsmgr);
11276     EXPECT_HR(hr, S_OK);
11277
11278     hr = IMXNamespaceManager_popContext(nsmgr);
11279     EXPECT_HR(hr, S_OK);
11280
11281     len = 100;
11282     buffW[0] = 0x1;
11283     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11284     EXPECT_HR(hr, E_FAIL);
11285     ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11286     ok(len == 100, "got %d\n", len);
11287
11288     len = 100;
11289     buffW[0] = 0x1;
11290     hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11291     EXPECT_HR(hr, S_OK);
11292     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
11293     ok(len == 3, "got %d\n", len);
11294
11295     IMXNamespaceManager_Release(nsmgr);
11296
11297     free_bstrs();
11298 }
11299
11300 static void test_mxnamespacemanager_override(void)
11301 {
11302     IMXNamespaceManager *nsmgr;
11303     WCHAR buffW[250];
11304     VARIANT_BOOL b;
11305     HRESULT hr;
11306     INT len;
11307
11308     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11309         &IID_IMXNamespaceManager, (void**)&nsmgr);
11310     EXPECT_HR(hr, S_OK);
11311
11312     len = sizeof(buffW)/sizeof(WCHAR);
11313     buffW[0] = 0;
11314     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11315     EXPECT_HR(hr, S_OK);
11316     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
11317
11318     len = sizeof(buffW)/sizeof(WCHAR);
11319     buffW[0] = 0;
11320     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11321     EXPECT_HR(hr, E_FAIL);
11322
11323     hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
11324     EXPECT_HR(hr, E_POINTER);
11325
11326     b = VARIANT_FALSE;
11327     hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
11328     EXPECT_HR(hr, S_OK);
11329     ok(b == VARIANT_TRUE, "got %d\n", b);
11330
11331     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
11332     EXPECT_HR(hr, S_OK);
11333
11334     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
11335     EXPECT_HR(hr, S_OK);
11336
11337     len = sizeof(buffW)/sizeof(WCHAR);
11338     buffW[0] = 0;
11339     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
11340     EXPECT_HR(hr, S_OK);
11341     ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
11342
11343     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
11344     EXPECT_HR(hr, S_OK);
11345
11346     len = sizeof(buffW)/sizeof(WCHAR);
11347     buffW[0] = 0;
11348     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11349     EXPECT_HR(hr, S_OK);
11350     ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
11351
11352     len = sizeof(buffW)/sizeof(WCHAR);
11353     buffW[0] = 0;
11354     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11355     EXPECT_HR(hr, S_OK);
11356     ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
11357
11358     len = sizeof(buffW)/sizeof(WCHAR);
11359     buffW[0] = 0;
11360     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
11361     EXPECT_HR(hr, S_OK);
11362     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
11363
11364     /* new prefix placed at index 1 always */
11365     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11366     EXPECT_HR(hr, S_OK);
11367
11368     len = sizeof(buffW)/sizeof(WCHAR);
11369     buffW[0] = 0;
11370     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11371     EXPECT_HR(hr, S_OK);
11372     ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
11373
11374     hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
11375     todo_wine EXPECT_HR(hr, E_FAIL);
11376
11377     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
11378     EXPECT_HR(hr, E_FAIL);
11379
11380     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
11381     EXPECT_HR(hr, E_FAIL);
11382
11383     hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
11384     EXPECT_HR(hr, S_OK);
11385
11386     hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
11387     EXPECT_HR(hr, S_FALSE);
11388
11389     len = sizeof(buffW)/sizeof(WCHAR);
11390     buffW[0] = 0;
11391     hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
11392     EXPECT_HR(hr, S_OK);
11393     ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
11394
11395     len = sizeof(buffW)/sizeof(WCHAR);
11396     buffW[0] = 0;
11397     hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
11398     EXPECT_HR(hr, S_OK);
11399     ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
11400
11401     IMXNamespaceManager_Release(nsmgr);
11402
11403     free_bstrs();
11404 }
11405
11406 static const DOMNodeType nodetypes_test[] =
11407 {
11408     NODE_ELEMENT,
11409     NODE_ATTRIBUTE,
11410     NODE_TEXT,
11411     NODE_CDATA_SECTION,
11412     NODE_ENTITY_REFERENCE,
11413     NODE_PROCESSING_INSTRUCTION,
11414     NODE_COMMENT,
11415     NODE_DOCUMENT_FRAGMENT,
11416     NODE_INVALID
11417 };
11418
11419 static void test_dispex(void)
11420 {
11421     const DOMNodeType *type = nodetypes_test;
11422     IXMLDOMImplementation *impl;
11423     IXMLDOMNodeList *node_list;
11424     IXMLDOMParseError *error;
11425     IXMLDOMNamedNodeMap *map;
11426     IXSLProcessor *processor;
11427     IXSLTemplate *template;
11428     IXMLDOMDocument *doc;
11429     IXMLHTTPRequest *req;
11430     IXMLDOMElement *elem;
11431     IDispatchEx *dispex;
11432     IXMLDOMNode *node;
11433     VARIANT_BOOL b;
11434     IUnknown *unk;
11435     HRESULT hr;
11436     DISPID did;
11437
11438     doc = create_document(&IID_IXMLDOMDocument);
11439
11440     IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
11441     test_domobj_dispex(unk);
11442     IUnknown_Release(unk);
11443
11444     for(; *type != NODE_INVALID; type++)
11445     {
11446         IXMLDOMNode *node;
11447         VARIANT v;
11448
11449         V_VT(&v) = VT_I2;
11450         V_I2(&v) = *type;
11451
11452         hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
11453         ok(hr == S_OK, "failed to create node type %d\n", *type);
11454
11455         IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
11456
11457         test_domobj_dispex(unk);
11458         IUnknown_Release(unk);
11459         IXMLDOMNode_Release(node);
11460     }
11461
11462     /* IXMLDOMNodeList */
11463     hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
11464     EXPECT_HR(hr, S_OK);
11465     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11466     test_domobj_dispex(unk);
11467     IUnknown_Release(unk);
11468     IXMLDOMNodeList_Release(node_list);
11469
11470     /* IXMLDOMNodeList for children list */
11471     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
11472     EXPECT_HR(hr, S_OK);
11473     IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11474     test_domobj_dispex(unk);
11475     IUnknown_Release(unk);
11476
11477     /* collection dispex test, empty collection */
11478     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
11479     EXPECT_HR(hr, S_OK);
11480     did = 0;
11481     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11482     EXPECT_HR(hr, S_OK);
11483     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11484     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11485     EXPECT_HR(hr, S_OK);
11486     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11487     IDispatchEx_Release(dispex);
11488
11489     IXMLDOMNodeList_Release(node_list);
11490
11491     /* IXMLDOMParseError */
11492     hr = IXMLDOMDocument_get_parseError(doc, &error);
11493     EXPECT_HR(hr, S_OK);
11494     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11495     test_domobj_dispex(unk);
11496     IUnknown_Release(unk);
11497     IXMLDOMParseError_Release(error);
11498
11499     /* IXMLDOMNamedNodeMap */
11500     hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
11501     EXPECT_HR(hr, S_OK);
11502
11503     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11504     EXPECT_HR(hr, S_OK);
11505     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11506     EXPECT_HR(hr, S_OK);
11507     IXMLDOMNodeList_Release(node_list);
11508
11509     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11510     EXPECT_HR(hr, S_OK);
11511     IXMLDOMNode_Release(node);
11512     hr = IXMLDOMElement_get_attributes(elem, &map);
11513     EXPECT_HR(hr, S_OK);
11514     IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11515     test_domobj_dispex(unk);
11516     IUnknown_Release(unk);
11517     /* collection dispex test */
11518     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11519     EXPECT_HR(hr, S_OK);
11520     did = 0;
11521     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11522     EXPECT_HR(hr, S_OK);
11523     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11524     IDispatchEx_Release(dispex);
11525
11526     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11527     EXPECT_HR(hr, S_OK);
11528     hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11529     EXPECT_HR(hr, S_OK);
11530     IXMLDOMNodeList_Release(node_list);
11531     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11532     EXPECT_HR(hr, S_OK);
11533     IXMLDOMNode_Release(node);
11534     hr = IXMLDOMElement_get_attributes(elem, &map);
11535     EXPECT_HR(hr, S_OK);
11536     /* collection dispex test, empty collection */
11537     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11538     EXPECT_HR(hr, S_OK);
11539     did = 0;
11540     hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11541     EXPECT_HR(hr, S_OK);
11542     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11543     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11544     EXPECT_HR(hr, S_OK);
11545     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11546     IDispatchEx_Release(dispex);
11547
11548     IXMLDOMNamedNodeMap_Release(map);
11549     IXMLDOMElement_Release(elem);
11550
11551     /* IXMLDOMImplementation */
11552     hr = IXMLDOMDocument_get_implementation(doc, &impl);
11553     EXPECT_HR(hr, S_OK);
11554
11555     hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11556     EXPECT_HR(hr, S_OK);
11557     IDispatchEx_Release(dispex);
11558     IXMLDOMImplementation_Release(impl);
11559
11560     IXMLDOMDocument_Release(doc);
11561
11562     /* IXMLHTTPRequest */
11563     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11564         &IID_IXMLHttpRequest, (void**)&req);
11565     if (hr == S_OK)
11566     {
11567         hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11568         EXPECT_HR(hr, E_NOINTERFACE);
11569         IXMLHTTPRequest_Release(req);
11570     }
11571
11572     /* IXSLTemplate */
11573     template = create_xsltemplate(&IID_IXSLTemplate);
11574     hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11575     EXPECT_HR(hr, S_OK);
11576     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11577     EXPECT_HR(hr, S_OK);
11578     test_domobj_dispex(unk);
11579     IUnknown_Release(unk);
11580     IDispatchEx_Release(dispex);
11581
11582     /* IXSLProcessor */
11583     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11584     EXPECT_HR(hr, S_OK);
11585     b = VARIANT_FALSE;
11586     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11587     EXPECT_HR(hr, S_OK);
11588     ok(b == VARIANT_TRUE, "got %d\n", b);
11589
11590     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11591     EXPECT_HR(hr, S_OK);
11592     IXMLDOMDocument_Release(doc);
11593
11594     hr = IXSLTemplate_createProcessor(template, &processor);
11595     EXPECT_HR(hr, S_OK);
11596     hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11597     EXPECT_HR(hr, S_OK);
11598     hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11599     EXPECT_HR(hr, S_OK);
11600     test_domobj_dispex(unk);
11601     IUnknown_Release(unk);
11602     IDispatchEx_Release(dispex);
11603
11604     IXSLProcessor_Release(processor);
11605     IXSLTemplate_Release(template);
11606
11607     free_bstrs();
11608 }
11609
11610 static void test_parseerror(void)
11611 {
11612     IXMLDOMParseError2 *error2;
11613     IXMLDOMParseError *error;
11614     IXMLDOMDocument *doc;
11615     HRESULT hr;
11616
11617     doc = create_document(&IID_IXMLDOMDocument);
11618
11619     hr = IXMLDOMDocument_get_parseError(doc, &error);
11620     EXPECT_HR(hr, S_OK);
11621
11622     hr = IXMLDOMParseError_get_line(error, NULL);
11623     EXPECT_HR(hr, E_INVALIDARG);
11624
11625     hr = IXMLDOMParseError_get_srcText(error, NULL);
11626     EXPECT_HR(hr, E_INVALIDARG);
11627
11628     hr = IXMLDOMParseError_get_linepos(error, NULL);
11629     EXPECT_HR(hr, E_INVALIDARG);
11630
11631     IXMLDOMParseError_Release(error);
11632     IXMLDOMDocument_Release(doc);
11633
11634     doc = create_document_version(60, &IID_IXMLDOMDocument);
11635     if (!doc) return;
11636     hr = IXMLDOMDocument_get_parseError(doc, &error);
11637     EXPECT_HR(hr, S_OK);
11638     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11639     EXPECT_HR(hr, S_OK);
11640     IXMLDOMParseError2_Release(error2);
11641     IXMLDOMParseError_Release(error);
11642     IXMLDOMDocument_Release(doc);
11643 }
11644
11645 static void test_getAttributeNode(void)
11646 {
11647     IXMLDOMAttribute *attr;
11648     IXMLDOMDocument *doc;
11649     IXMLDOMElement *elem;
11650     VARIANT_BOOL v;
11651     HRESULT hr;
11652     BSTR str;
11653
11654     doc = create_document(&IID_IXMLDOMDocument);
11655
11656     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11657     EXPECT_HR(hr, S_OK);
11658
11659     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11660     EXPECT_HR(hr, S_OK);
11661
11662     str = SysAllocString(nonexistent_fileW);
11663     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11664     EXPECT_HR(hr, E_FAIL);
11665
11666     attr = (IXMLDOMAttribute*)0xdeadbeef;
11667     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11668     EXPECT_HR(hr, E_FAIL);
11669     ok(attr == NULL, "got %p\n", attr);
11670     SysFreeString(str);
11671
11672     str = SysAllocString(nonexistent_attrW);
11673     hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11674     EXPECT_HR(hr, S_FALSE);
11675
11676     attr = (IXMLDOMAttribute*)0xdeadbeef;
11677     hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11678     EXPECT_HR(hr, S_FALSE);
11679     ok(attr == NULL, "got %p\n", attr);
11680     SysFreeString(str);
11681
11682     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11683     EXPECT_HR(hr, S_OK);
11684     IXMLDOMAttribute_Release(attr);
11685
11686     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11687     EXPECT_HR(hr, S_FALSE);
11688
11689     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11690     EXPECT_HR(hr, S_OK);
11691     IXMLDOMAttribute_Release(attr);
11692
11693     IXMLDOMElement_Release(elem);
11694     IXMLDOMDocument_Release(doc);
11695     free_bstrs();
11696 }
11697
11698 typedef struct {
11699     DOMNodeType type;
11700     const char *name;
11701     REFIID iids[3];
11702 } supporterror_t;
11703
11704 static const supporterror_t supporterror_test[] = {
11705     { NODE_ELEMENT,                "element",   { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11706     { NODE_ATTRIBUTE,              "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11707     { NODE_CDATA_SECTION,          "cdata",     { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11708     { NODE_ENTITY_REFERENCE,       "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11709     { NODE_PROCESSING_INSTRUCTION, "pi",        { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11710     { NODE_COMMENT,                "comment",   { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11711     { NODE_DOCUMENT_FRAGMENT,      "fragment",  { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11712     { NODE_INVALID }
11713 };
11714
11715 static void test_supporterrorinfo(void)
11716 {
11717     static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11718                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11719     const supporterror_t *ptr = supporterror_test;
11720     ISupportErrorInfo *errorinfo, *info2;
11721     IXMLDOMNamedNodeMap *map, *map2;
11722     IXMLDOMDocument *doc;
11723     IXMLDOMElement *elem;
11724     VARIANT_BOOL b;
11725     IUnknown *unk;
11726     REFIID *iid;
11727     void *dummy;
11728     HRESULT hr;
11729
11730     doc = create_document_version(60, &IID_IXMLDOMDocument3);
11731     if (!doc) return;
11732
11733     EXPECT_REF(doc, 1);
11734     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11735     EXPECT_HR(hr, S_OK);
11736     EXPECT_REF(doc, 1);
11737     ISupportErrorInfo_AddRef(errorinfo);
11738     EXPECT_REF(errorinfo, 2);
11739     EXPECT_REF(doc, 1);
11740     ISupportErrorInfo_Release(errorinfo);
11741
11742     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11743     EXPECT_HR(hr, S_OK);
11744     ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11745
11746     /* error interface can't be queried back for DOM interface */
11747     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11748     EXPECT_HR(hr, E_NOINTERFACE);
11749     hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11750     EXPECT_HR(hr, E_NOINTERFACE);
11751
11752     ISupportErrorInfo_Release(info2);
11753
11754     iid = iids;
11755     while (*iid)
11756     {
11757         hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11758         EXPECT_HR(hr, S_OK);
11759         if (hr == S_OK)
11760         {
11761             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11762             ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
11763             IUnknown_Release(unk);
11764         }
11765
11766         iid++;
11767     }
11768
11769     ISupportErrorInfo_Release(errorinfo);
11770
11771     while (ptr->type != NODE_INVALID)
11772     {
11773         IXMLDOMNode *node;
11774         VARIANT type;
11775
11776         V_VT(&type) = VT_I1;
11777         V_I1(&type) = ptr->type;
11778
11779         hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11780         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11781
11782         EXPECT_REF(node, 1);
11783         hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11784         ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11785         EXPECT_REF(node, 1);
11786
11787         hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11788         ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11789
11790         iid = ptr->iids;
11791
11792         while (*iid)
11793         {
11794             hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11795             if (hr == S_OK)
11796             {
11797                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11798                 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
11799                 IUnknown_Release(unk);
11800             }
11801
11802             iid++;
11803         }
11804
11805         ISupportErrorInfo_Release(errorinfo);
11806         IXMLDOMNode_Release(node);
11807         ptr++;
11808     }
11809
11810     /* IXMLDOMNamedNodeMap */
11811     b = VARIANT_FALSE;
11812     hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11813     EXPECT_HR(hr, S_OK);
11814     ok(b == VARIANT_TRUE, "got %d\n", b);
11815
11816     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11817     EXPECT_HR(hr, S_OK);
11818
11819     hr = IXMLDOMElement_get_attributes(elem, &map);
11820     EXPECT_HR(hr, S_OK);
11821
11822     EXPECT_REF(map, 1);
11823     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11824     EXPECT_HR(hr, S_OK);
11825     EXPECT_REF(map, 2);
11826
11827     hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11828     EXPECT_HR(hr, S_OK);
11829
11830     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11831     EXPECT_HR(hr, S_OK);
11832     ok(map == map2, "got %p\n", map2);
11833     IXMLDOMNamedNodeMap_Release(map2);
11834
11835     EXPECT_REF(errorinfo, 2);
11836     hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11837     EXPECT_HR(hr, S_OK);
11838     EXPECT_REF(errorinfo, 3);
11839     EXPECT_REF(map, 3);
11840     IUnknown_Release(unk);
11841
11842     ISupportErrorInfo_Release(errorinfo);
11843     IXMLDOMNamedNodeMap_Release(map);
11844     IXMLDOMElement_Release(elem);
11845
11846     IXMLDOMDocument_Release(doc);
11847     free_bstrs();
11848 }
11849
11850 typedef struct {
11851     DOMNodeType type;
11852     const char *name;
11853     const char *put_content;
11854     HRESULT put_hr;
11855     VARTYPE get_vt;
11856     HRESULT get_hr;
11857 } node_value_t;
11858
11859 static const node_value_t nodevalue_test[] = {
11860     { NODE_ELEMENT,                "element",   "",             E_FAIL, VT_NULL, S_FALSE },
11861     { NODE_ATTRIBUTE,              "attr",      "value",        S_OK,   VT_BSTR, S_OK },
11862     { NODE_TEXT,                   "text",      "textdata",     S_OK,   VT_BSTR, S_OK },
11863     { NODE_CDATA_SECTION ,         "cdata",     "cdata data",   S_OK,   VT_BSTR, S_OK },
11864     { NODE_ENTITY_REFERENCE,       "entityref", "ref",          E_FAIL, VT_NULL, S_FALSE },
11865     { NODE_PROCESSING_INSTRUCTION, "pi",        "instr",        S_OK,   VT_BSTR, S_OK },
11866     { NODE_COMMENT,                "comment",   "comment data", S_OK,   VT_BSTR, S_OK },
11867     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   "",             E_FAIL, VT_NULL, S_FALSE },
11868     { NODE_INVALID }
11869 };
11870
11871 static void test_nodeValue(void)
11872 {
11873     const node_value_t *ptr = nodevalue_test;
11874     IXMLDOMDocument *doc;
11875     HRESULT hr;
11876
11877     doc = create_document(&IID_IXMLDOMDocument);
11878     if (!doc) return;
11879
11880     while (ptr->type != NODE_INVALID)
11881     {
11882         IXMLDOMNode *node;
11883         VARIANT v;
11884
11885         V_VT(&v) = VT_I2;
11886         V_I2(&v) = ptr->type;
11887
11888         hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11889         ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11890
11891         hr = IXMLDOMNode_get_nodeValue(node, NULL);
11892         ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11893
11894         V_VT(&v) = VT_BSTR;
11895         V_BSTR(&v) = _bstr_(ptr->put_content);
11896         hr = IXMLDOMNode_put_nodeValue(node, v);
11897         ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11898
11899         V_VT(&v) = VT_EMPTY;
11900         hr = IXMLDOMNode_get_nodeValue(node, &v);
11901         ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11902         ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11903         if (hr == S_OK)
11904             ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11905                 wine_dbgstr_w(V_BSTR(&v)));
11906         VariantClear(&v);
11907
11908         IXMLDOMNode_Release(node);
11909
11910         ptr++;
11911     }
11912
11913     IXMLDOMDocument_Release(doc);
11914 }
11915
11916 static const char namespacesA[] =
11917 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11918 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11919 "     <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11920 "     <ns1:elem3/>"
11921 "     <ns1:elem4/>"
11922 "     <elem5 xmlns=\"http://blahblah.org\"/>"
11923 "     <ns1:elem6>true</ns1:elem6>"
11924 "   </ns1:elem1>";
11925
11926 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11927 static const char xsd_schema1_xml[] =
11928 "<?xml version='1.0'?>"
11929 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11930 "            targetNamespace='x-schema:test1.xsd'>"
11931 "   <element name='root'>"
11932 "       <complexType>"
11933 "           <sequence maxOccurs='unbounded'>"
11934 "               <any/>"
11935 "           </sequence>"
11936 "       </complexType>"
11937 "   </element>"
11938 "</schema>";
11939
11940 static void test_get_namespaces(void)
11941 {
11942     IXMLDOMSchemaCollection *collection, *collection2;
11943     IXMLDOMDocument2 *doc, *doc2;
11944     IEnumVARIANT *enumv, *enum2;
11945     IUnknown *unk1, *unk2;
11946     IXMLDOMNode *node;
11947     VARIANT_BOOL b;
11948     HRESULT hr;
11949     VARIANT v;
11950     LONG len;
11951     BSTR s;
11952
11953     doc = create_document(&IID_IXMLDOMDocument2);
11954     if (!doc) return;
11955
11956     /* null pointer */
11957     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11958     EXPECT_HR(hr, E_POINTER);
11959
11960     /* no document loaded */
11961     collection = (void*)0xdeadbeef;
11962     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11963     EXPECT_HR(hr, S_OK);
11964     if (hr != S_OK)
11965     {
11966         IXMLDOMDocument2_Release(doc);
11967         return;
11968     }
11969     EXPECT_REF(collection, 2);
11970
11971     collection2 = (void*)0xdeadbeef;
11972     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11973     EXPECT_HR(hr, S_OK);
11974     ok(collection == collection2, "got %p\n", collection2);
11975     EXPECT_REF(collection, 3);
11976     IXMLDOMSchemaCollection_Release(collection);
11977
11978     len = -1;
11979     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11980     EXPECT_HR(hr, S_OK);
11981     ok(len == 0, "got %d\n", len);
11982     IXMLDOMSchemaCollection_Release(collection);
11983
11984     /* now with document */
11985     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11986     EXPECT_HR(hr, S_OK);
11987
11988     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11989     EXPECT_HR(hr, S_OK);
11990
11991     len = -1;
11992     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11993     EXPECT_HR(hr, S_OK);
11994     ok(len == 2, "got %d\n", len);
11995
11996     /* try to lookup some uris */
11997     node = (void*)0xdeadbeef;
11998     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11999     EXPECT_HR(hr, S_OK);
12000     ok(node == NULL, "got %p\n", node);
12001
12002     node = (void*)0xdeadbeef;
12003     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
12004     EXPECT_HR(hr, S_OK);
12005     ok(node == NULL, "got %p\n", node);
12006
12007     /* load schema and try to add it */
12008     doc2 = create_document(&IID_IXMLDOMDocument2);
12009     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
12010     EXPECT_HR(hr, S_OK);
12011
12012     V_VT(&v) = VT_DISPATCH;
12013     V_DISPATCH(&v) = (IDispatch*)doc2;
12014     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
12015     EXPECT_HR(hr, E_FAIL);
12016
12017     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
12018     EXPECT_HR(hr, S_OK);
12019     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
12020     SysFreeString(s);
12021
12022     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
12023     EXPECT_HR(hr, S_OK);
12024     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
12025     SysFreeString(s);
12026
12027     s = (void*)0xdeadbeef;
12028     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
12029     EXPECT_HR(hr, E_FAIL);
12030     ok(s == (void*)0xdeadbeef, "got %p\n", s);
12031
12032     /* enumerate */
12033     enumv = (void*)0xdeadbeef;
12034     EXPECT_REF(collection, 2);
12035     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
12036     EXPECT_HR(hr, S_OK);
12037     EXPECT_REF(collection, 3);
12038     ok(enumv != NULL, "got %p\n", enumv);
12039
12040     hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IUnknown, (void**)&unk1);
12041     EXPECT_HR(hr, S_OK);
12042     hr = IEnumVARIANT_QueryInterface(enumv, &IID_IUnknown, (void**)&unk2);
12043     EXPECT_HR(hr, S_OK);
12044     ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
12045     IUnknown_Release(unk1);
12046     IUnknown_Release(unk2);
12047
12048     hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2);
12049     EXPECT_HR(hr, E_NOINTERFACE);
12050
12051     V_VT(&v) = VT_EMPTY;
12052     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12053     EXPECT_HR(hr, S_OK);
12054     ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
12055     ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
12056     VariantClear(&v);
12057
12058     V_VT(&v) = VT_EMPTY;
12059     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12060     EXPECT_HR(hr, S_OK);
12061     ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
12062     ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
12063     VariantClear(&v);
12064
12065     V_VT(&v) = VT_NULL;
12066     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12067     EXPECT_HR(hr, S_FALSE);
12068     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
12069
12070     IEnumVARIANT_Release(enumv);
12071     IXMLDOMSchemaCollection_Release(collection);
12072
12073     IXMLDOMDocument2_Release(doc);
12074
12075     /* now with CLSID_DOMDocument60 */
12076     doc = create_document_version(60, &IID_IXMLDOMDocument2);
12077     if (!doc) return;
12078
12079     /* null pointer */
12080     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
12081     EXPECT_HR(hr, E_POINTER);
12082
12083     /* no document loaded */
12084     collection = (void*)0xdeadbeef;
12085     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12086     EXPECT_HR(hr, S_OK);
12087     if (hr != S_OK)
12088     {
12089         IXMLDOMDocument2_Release(doc);
12090         return;
12091     }
12092     EXPECT_REF(collection, 2);
12093
12094     collection2 = (void*)0xdeadbeef;
12095     hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
12096     EXPECT_HR(hr, S_OK);
12097     ok(collection == collection2, "got %p\n", collection2);
12098     EXPECT_REF(collection, 3);
12099     IXMLDOMSchemaCollection_Release(collection);
12100
12101     len = -1;
12102     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12103     EXPECT_HR(hr, S_OK);
12104     ok(len == 0, "got %d\n", len);
12105     IXMLDOMSchemaCollection_Release(collection);
12106
12107     /* now with document */
12108     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
12109     EXPECT_HR(hr, S_OK);
12110
12111     hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12112     EXPECT_HR(hr, S_OK);
12113
12114     len = -1;
12115     hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12116     EXPECT_HR(hr, S_OK);
12117     ok(len == 2, "got %d\n", len);
12118
12119     /* try to lookup some uris */
12120     node = (void*)0xdeadbeef;
12121     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
12122     EXPECT_HR(hr, E_NOTIMPL);
12123     ok(node == (void*)0xdeadbeef, "got %p\n", node);
12124
12125     /* load schema and try to add it */
12126     doc2 = create_document(&IID_IXMLDOMDocument2);
12127     hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
12128     EXPECT_HR(hr, S_OK);
12129
12130     V_VT(&v) = VT_DISPATCH;
12131     V_DISPATCH(&v) = (IDispatch*)doc2;
12132     hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
12133     EXPECT_HR(hr, E_FAIL);
12134     IXMLDOMDocument2_Release(doc2);
12135
12136     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
12137     EXPECT_HR(hr, S_OK);
12138     ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
12139     SysFreeString(s);
12140
12141     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
12142     EXPECT_HR(hr, S_OK);
12143     ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
12144     SysFreeString(s);
12145
12146     s = (void*)0xdeadbeef;
12147     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
12148     EXPECT_HR(hr, E_FAIL);
12149     ok(s == (void*)0xdeadbeef, "got %p\n", s);
12150
12151     /* enumerate */
12152     enumv = (void*)0xdeadbeef;
12153     hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
12154     EXPECT_HR(hr, S_OK);
12155     ok(enumv != NULL, "got %p\n", enumv);
12156
12157     V_VT(&v) = VT_EMPTY;
12158     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12159     EXPECT_HR(hr, S_OK);
12160     ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
12161     ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
12162     VariantClear(&v);
12163
12164     V_VT(&v) = VT_EMPTY;
12165     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12166     EXPECT_HR(hr, S_OK);
12167     ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
12168     ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
12169     VariantClear(&v);
12170
12171     V_VT(&v) = VT_NULL;
12172     hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12173     EXPECT_HR(hr, S_FALSE);
12174     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
12175
12176     IEnumVARIANT_Release(enumv);
12177     IXMLDOMSchemaCollection_Release(collection);
12178     IXMLDOMDocument2_Release(doc);
12179     free_bstrs();
12180 }
12181
12182 static DOMNodeType put_data_types[] = {
12183     NODE_TEXT,
12184     NODE_CDATA_SECTION,
12185     NODE_PROCESSING_INSTRUCTION,
12186     NODE_COMMENT,
12187     NODE_INVALID
12188 };
12189
12190 static void test_put_data(void)
12191 {
12192     static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0};
12193     WCHAR buff[100], *data;
12194     IXMLDOMDocument *doc;
12195     DOMNodeType *type;
12196     IXMLDOMText *text;
12197     IXMLDOMNode *node;
12198     VARIANT v;
12199     BSTR get_data;
12200     HRESULT hr;
12201
12202     doc = create_document(&IID_IXMLDOMDocument);
12203     if (!doc) return;
12204
12205     memcpy(&buff[2], test_data, sizeof(test_data));
12206     /* just a big length */
12207     *(DWORD*)buff = 0xf0f0;
12208     data = &buff[2];
12209
12210     type = put_data_types;
12211     while (*type != NODE_INVALID)
12212     {
12213        V_VT(&v) = VT_I2;
12214        V_I2(&v) = *type;
12215
12216        hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12217        EXPECT_HR(hr, S_OK);
12218
12219        /* put_data() is interface-specific */
12220        switch (*type)
12221        {
12222            case NODE_TEXT:
12223            {
12224               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12225               EXPECT_HR(hr, S_OK);
12226               hr = IXMLDOMText_put_data(text, data);
12227               EXPECT_HR(hr, S_OK);
12228
12229               hr = IXMLDOMText_get_data(text, &get_data);
12230               EXPECT_HR(hr, S_OK);
12231
12232               IXMLDOMText_Release(text);
12233               break;
12234            }
12235            case NODE_CDATA_SECTION:
12236            {
12237               IXMLDOMCDATASection *cdata;
12238
12239               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
12240               EXPECT_HR(hr, S_OK);
12241               hr = IXMLDOMCDATASection_put_data(cdata, data);
12242               EXPECT_HR(hr, S_OK);
12243
12244               hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
12245               EXPECT_HR(hr, S_OK);
12246
12247               IXMLDOMCDATASection_Release(cdata);
12248               break;
12249            }
12250            case NODE_PROCESSING_INSTRUCTION:
12251            {
12252               IXMLDOMProcessingInstruction *pi;
12253
12254               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
12255               EXPECT_HR(hr, S_OK);
12256               hr = IXMLDOMProcessingInstruction_put_data(pi, data);
12257               EXPECT_HR(hr, S_OK);
12258
12259               hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
12260               EXPECT_HR(hr, S_OK);
12261
12262               IXMLDOMProcessingInstruction_Release(pi);
12263               break;
12264            }
12265            case NODE_COMMENT:
12266            {
12267               IXMLDOMComment *comment;
12268
12269               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
12270               EXPECT_HR(hr, S_OK);
12271               hr = IXMLDOMComment_put_data(comment, data);
12272               EXPECT_HR(hr, S_OK);
12273
12274               hr = IXMLDOMComment_get_data(comment, &get_data);
12275               EXPECT_HR(hr, S_OK);
12276
12277               IXMLDOMComment_Release(comment);
12278               break;
12279            }
12280            default:
12281               break;
12282        }
12283
12284        /* compare */
12285        ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
12286            wine_dbgstr_w(data));
12287        SysFreeString(get_data);
12288
12289        IXMLDOMNode_Release(node);
12290        type++;
12291     }
12292
12293     /* \r\n sequence is never escaped */
12294     V_VT(&v) = VT_I2;
12295     V_I2(&v) = NODE_TEXT;
12296
12297     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12298     ok(hr == S_OK, "got 0x%08x\n", hr);
12299
12300     IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12301
12302     hr = IXMLDOMText_put_data(text, _bstr_("\r\n"));
12303     ok(hr == S_OK, "got 0x%08x\n", hr);
12304
12305     hr = IXMLDOMText_get_data(text, &get_data);
12306     ok(hr == S_OK, "got 0x%08x\n", hr);
12307 todo_wine
12308     ok(!lstrcmpW(get_data, _bstr_("\n")), "got %s\n", wine_dbgstr_w(get_data));
12309     SysFreeString(get_data);
12310
12311     hr = IXMLDOMText_get_xml(text, &get_data);
12312     ok(hr == S_OK, "got 0x%08x\n", hr);
12313     ok(!lstrcmpW(get_data, _bstr_("\r\n")), "got %s\n", wine_dbgstr_w(get_data));
12314     SysFreeString(get_data);
12315
12316     IXMLDOMText_Release(text);
12317     IXMLDOMNode_Release(node);
12318
12319     IXMLDOMDocument_Release(doc);
12320     free_bstrs();
12321 }
12322
12323 static void test_putref_schemas(void)
12324 {
12325     IXMLDOMSchemaCollection *cache;
12326     IXMLDOMDocument2 *doc;
12327     VARIANT schema;
12328     HRESULT hr;
12329
12330     doc = create_document(&IID_IXMLDOMDocument2);
12331     if (!doc) return;
12332     cache = create_cache(&IID_IXMLDOMSchemaCollection);
12333
12334     /* set to NULL iface when no schema is set */
12335     V_VT(&schema) = VT_DISPATCH;
12336     V_DISPATCH(&schema) = NULL;
12337     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12338     EXPECT_HR(hr, S_OK);
12339
12340     V_VT(&schema) = VT_UNKNOWN;
12341     V_UNKNOWN(&schema) = NULL;
12342     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12343     EXPECT_HR(hr, S_OK);
12344
12345     /* set as VT_DISPATCH, reset with it */
12346     V_VT(&schema) = VT_DISPATCH;
12347     V_DISPATCH(&schema) = (IDispatch*)cache;
12348     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12349     EXPECT_HR(hr, S_OK);
12350
12351     V_DISPATCH(&schema) = NULL;
12352     hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12353     EXPECT_HR(hr, S_OK);
12354     ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12355
12356     V_VT(&schema) = VT_DISPATCH;
12357     V_DISPATCH(&schema) = NULL;
12358     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12359     EXPECT_HR(hr, S_OK);
12360
12361     V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12362     V_VT(&schema) = VT_I2;
12363     hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12364     EXPECT_HR(hr, S_FALSE);
12365     ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12366     ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12367
12368     /* set as VT_UNKNOWN, reset with it */
12369     V_VT(&schema) = VT_UNKNOWN;
12370     V_UNKNOWN(&schema) = (IUnknown*)cache;
12371     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12372     EXPECT_HR(hr, S_OK);
12373
12374     V_DISPATCH(&schema) = NULL;
12375     hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12376     EXPECT_HR(hr, S_OK);
12377     ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12378
12379     V_VT(&schema) = VT_UNKNOWN;
12380     V_UNKNOWN(&schema) = NULL;
12381     hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12382     EXPECT_HR(hr, S_OK);
12383
12384     V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12385     V_VT(&schema) = VT_I2;
12386     hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12387     EXPECT_HR(hr, S_FALSE);
12388     ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12389     ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12390
12391     IXMLDOMSchemaCollection_Release(cache);
12392     IXMLDOMDocument2_Release(doc);
12393 }
12394
12395 static void test_namedmap_newenum(void)
12396 {
12397     IEnumVARIANT *enum1, *enum2, *enum3;
12398     IXMLDOMNamedNodeMap *map;
12399     IUnknown *unk1, *unk2;
12400     IXMLDOMDocument *doc;
12401     IXMLDOMElement *elem;
12402     IXMLDOMNode *node;
12403     VARIANT_BOOL b;
12404     HRESULT hr;
12405     VARIANT v;
12406     BSTR str;
12407
12408     doc = create_document(&IID_IXMLDOMDocument);
12409
12410     hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b);
12411     EXPECT_HR(hr, S_OK);
12412
12413     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12414     EXPECT_HR(hr, S_OK);
12415
12416     hr = IXMLDOMElement_get_attributes(elem, &map);
12417     EXPECT_HR(hr, S_OK);
12418     IXMLDOMElement_Release(elem);
12419
12420     enum1 = NULL;
12421     EXPECT_REF(map, 1);
12422     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1);
12423     EXPECT_HR(hr, S_OK);
12424     ok(enum1 != NULL, "got %p\n", enum1);
12425     EXPECT_REF(map, 1);
12426     EXPECT_REF(enum1, 2);
12427
12428     enum2 = NULL;
12429     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2);
12430     EXPECT_HR(hr, S_OK);
12431     ok(enum2 == enum1, "got %p\n", enum2);
12432
12433     IEnumVARIANT_Release(enum2);
12434
12435     EXPECT_REF(map, 1);
12436     hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2);
12437     EXPECT_HR(hr, S_OK);
12438     EXPECT_REF(map, 2);
12439     EXPECT_REF(enum2, 1);
12440     ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
12441
12442     IEnumVARIANT_Release(enum1);
12443
12444     /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
12445     hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1);
12446     EXPECT_HR(hr, S_OK);
12447     hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
12448     EXPECT_HR(hr, S_OK);
12449     EXPECT_REF(map, 3);
12450     EXPECT_REF(enum2, 2);
12451     ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
12452     IUnknown_Release(unk1);
12453     IUnknown_Release(unk2);
12454
12455     hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3);
12456     EXPECT_HR(hr, S_OK);
12457     ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
12458     IEnumVARIANT_Release(enum3);
12459
12460     /* iteration tests */
12461     hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
12462     EXPECT_HR(hr, S_OK);
12463     hr = IXMLDOMNode_get_nodeName(node, &str);
12464     EXPECT_HR(hr, S_OK);
12465     ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12466     SysFreeString(str);
12467     IXMLDOMNode_Release(node);
12468
12469     hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12470     EXPECT_HR(hr, S_OK);
12471     hr = IXMLDOMNode_get_nodeName(node, &str);
12472     EXPECT_HR(hr, S_OK);
12473     ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12474     SysFreeString(str);
12475     IXMLDOMNode_Release(node);
12476
12477     V_VT(&v) = VT_EMPTY;
12478     hr = IEnumVARIANT_Next(enum2, 1, &v, NULL);
12479     EXPECT_HR(hr, S_OK);
12480     ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
12481     hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
12482     EXPECT_HR(hr, S_OK);
12483     hr = IXMLDOMNode_get_nodeName(node, &str);
12484     EXPECT_HR(hr, S_OK);
12485     ok(!lstrcmpW(str, _bstr_("attr1")), "got node name %s\n", wine_dbgstr_w(str));
12486     SysFreeString(str);
12487     IXMLDOMNode_Release(node);
12488     VariantClear(&v);
12489
12490     hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12491     EXPECT_HR(hr, S_OK);
12492     hr = IXMLDOMNode_get_nodeName(node, &str);
12493     EXPECT_HR(hr, S_OK);
12494     ok(!lstrcmpW(str, _bstr_("attr2")), "got %s\n", wine_dbgstr_w(str));
12495     SysFreeString(str);
12496     IXMLDOMNode_Release(node);
12497
12498     IEnumVARIANT_Release(enum2);
12499     IXMLDOMNamedNodeMap_Release(map);
12500     IXMLDOMDocument_Release(doc);
12501 }
12502
12503 static const char xsltext_xsl[] =
12504 "<?xml version=\"1.0\"?>"
12505 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
12506 "<xsl:output method=\"html\" encoding=\"us-ascii\"/>"
12507 "<xsl:template match=\"/\">"
12508 "    <xsl:choose>"
12509 "        <xsl:when test=\"testkey\">"
12510 "            <xsl:text>testdata</xsl:text>"
12511 "        </xsl:when>"
12512 "    </xsl:choose>"
12513 "</xsl:template>"
12514 "</xsl:stylesheet>";
12515
12516 static void test_xsltext(void)
12517 {
12518     IXMLDOMDocument *doc, *doc2;
12519     VARIANT_BOOL b;
12520     HRESULT hr;
12521     BSTR ret;
12522
12523     doc = create_document(&IID_IXMLDOMDocument);
12524     if (!doc) return;
12525
12526     doc2 = create_document(&IID_IXMLDOMDocument);
12527
12528     hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
12529     EXPECT_HR(hr, S_OK);
12530
12531     hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b);
12532     EXPECT_HR(hr, S_OK);
12533
12534     hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
12535     EXPECT_HR(hr, S_OK);
12536     ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret));
12537     SysFreeString(ret);
12538
12539     IXMLDOMDocument_Release(doc2);
12540     IXMLDOMDocument_Release(doc);
12541     free_bstrs();
12542 }
12543
12544 START_TEST(domdoc)
12545 {
12546     IXMLDOMDocument *doc;
12547     IUnknown *unk;
12548     HRESULT hr;
12549
12550     hr = CoInitialize( NULL );
12551     ok( hr == S_OK, "failed to init com\n");
12552     if (hr != S_OK) return;
12553
12554     test_XMLHTTP();
12555
12556     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
12557     if (hr != S_OK)
12558     {
12559         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
12560         return;
12561     }
12562
12563     IXMLDOMDocument_Release(doc);
12564
12565     test_domdoc();
12566     test_persiststreaminit();
12567     test_domnode();
12568     test_refs();
12569     test_create();
12570     test_getElementsByTagName();
12571     test_get_text();
12572     test_get_childNodes();
12573     test_get_firstChild();
12574     test_get_lastChild();
12575     test_removeChild();
12576     test_replaceChild();
12577     test_removeNamedItem();
12578     test_IXMLDOMDocument2();
12579     test_whitespace();
12580     test_XPath();
12581     test_XSLPattern();
12582     test_cloneNode();
12583     test_xmlTypes();
12584     test_save();
12585     test_testTransforms();
12586     test_namespaces_basic();
12587     test_namespaces_change();
12588     test_FormattingXML();
12589     test_nodeTypedValue();
12590     test_TransformWithLoadingLocalFile();
12591     test_put_nodeValue();
12592     test_document_IObjectSafety();
12593     test_splitText();
12594     test_getQualifiedItem();
12595     test_removeQualifiedItem();
12596     test_get_ownerDocument();
12597     test_setAttributeNode();
12598     test_put_dataType();
12599     test_createNode();
12600     test_get_prefix();
12601     test_default_properties();
12602     test_selectSingleNode();
12603     test_events();
12604     test_createProcessingInstruction();
12605     test_put_nodeTypedValue();
12606     test_get_xml();
12607     test_insertBefore();
12608     test_appendChild();
12609     test_get_doctype();
12610     test_get_tagName();
12611     test_get_dataType();
12612     test_get_nodeTypeString();
12613     test_get_attributes();
12614     test_selection();
12615     test_load();
12616     test_dispex();
12617     test_parseerror();
12618     test_getAttributeNode();
12619     test_supporterrorinfo();
12620     test_nodeValue();
12621     test_get_namespaces();
12622     test_put_data();
12623     test_putref_schemas();
12624     test_namedmap_newenum();
12625
12626     test_xsltemplate();
12627     test_xsltext();
12628
12629     hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
12630         &IID_IMXNamespaceManager, (void**)&unk);
12631     if (hr == S_OK)
12632     {
12633         test_mxnamespacemanager();
12634         test_mxnamespacemanager_override();
12635
12636         IUnknown_Release(unk);
12637     }
12638     else
12639         win_skip("MXNamespaceManager is not available\n");
12640
12641     CoUninitialize();
12642 }