03ac01675d0edf4c4aae3b6982e82c9992d833b0
[reactos.git] / modules / rostests / winetests / msxml3 / 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-2013 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 #include "precomp.h"
25
26 #include <asptlb.h>
27
28 /* undef the #define in msxml2 so that we can access all versions */
29 #undef CLSID_DOMDocument
30
31 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
32 DEFINE_GUID(IID_transformdest_unknown,0xf5078f3a,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21);
33
34 static int g_unexpectedcall, g_expectedcall;
35
36 struct msxmlsupported_data_t
37 {
38 const GUID *clsid;
39 const char *name;
40 const IID *ifaces[3];
41 BOOL supported[3];
42 };
43
44 static struct msxmlsupported_data_t domdoc_support_data[] =
45 {
46 { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
47 { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
48 { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
49 { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
50 { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
51 { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
52 { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
53 { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} },
54 { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
55 { NULL }
56 };
57
58 static const char *debugstr_msxml_guid(REFIID riid)
59 {
60 if(!riid)
61 return "(null)";
62
63 if (IsEqualIID(&IID_IXMLDOMDocument, riid))
64 return "IXMLDOMDocument";
65 else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
66 return "IXMLDOMDocument2";
67 else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
68 return "IXMLDOMDocument3";
69 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
70 return "IXMLDOMSchemaCollection";
71 else if (IsEqualIID(&IID_IXSLTemplate, riid))
72 return "IXSLTemplate";
73 else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
74 return "IMXNamespaceManager";
75 else
76 return wine_dbgstr_guid(riid);
77 }
78
79 static void get_class_support_data(struct msxmlsupported_data_t *table)
80 {
81 while (table->clsid)
82 {
83 IUnknown *unk;
84 HRESULT hr;
85 int i;
86
87 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
88 {
89 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
90 if (hr == S_OK) IUnknown_Release(unk);
91
92 table->supported[i] = hr == S_OK;
93 if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
94 }
95
96 table++;
97 }
98 }
99
100 static BOOL is_clsid_supported(const GUID *clsid, REFIID riid)
101 {
102 const struct msxmlsupported_data_t *table = domdoc_support_data;
103 while (table->clsid)
104 {
105 if (table->clsid == clsid)
106 {
107 int i;
108
109 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
110 if (table->ifaces[i] == riid) return table->supported[i];
111 }
112
113 table++;
114 }
115 return FALSE;
116 }
117
118 typedef struct
119 {
120 IDispatch IDispatch_iface;
121 LONG ref;
122 } dispevent;
123
124 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
125 {
126 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
127 }
128
129 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
130 {
131 *ppvObject = NULL;
132
133 if ( IsEqualGUID( riid, &IID_IDispatch) ||
134 IsEqualGUID( riid, &IID_IUnknown) )
135 {
136 *ppvObject = iface;
137 }
138 else
139 return E_NOINTERFACE;
140
141 IDispatch_AddRef( iface );
142
143 return S_OK;
144 }
145
146 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
147 {
148 dispevent *This = impl_from_IDispatch( iface );
149 return InterlockedIncrement( &This->ref );
150 }
151
152 static ULONG WINAPI dispevent_Release(IDispatch *iface)
153 {
154 dispevent *This = impl_from_IDispatch( iface );
155 ULONG ref = InterlockedDecrement( &This->ref );
156
157 if (ref == 0)
158 HeapFree(GetProcessHeap(), 0, This);
159
160 return ref;
161 }
162
163 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
164 {
165 g_unexpectedcall++;
166 *pctinfo = 0;
167 return S_OK;
168 }
169
170 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
171 LCID lcid, ITypeInfo **ppTInfo)
172 {
173 g_unexpectedcall++;
174 return S_OK;
175 }
176
177 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
178 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
179 {
180 g_unexpectedcall++;
181 return S_OK;
182 }
183
184 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
185 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
186 EXCEPINFO *excepInfo, UINT *argErr)
187 {
188 ok(member == 0, "expected 0 member, got %d\n", member);
189 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
190 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
191
192 ok(params->cArgs == 0, "got %d\n", params->cArgs);
193 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
194 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
195 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
196
197 ok(result == NULL, "got %p\n", result);
198 ok(excepInfo == NULL, "got %p\n", excepInfo);
199 ok(argErr == NULL, "got %p\n", argErr);
200
201 g_expectedcall++;
202 return E_FAIL;
203 }
204
205 static const IDispatchVtbl dispeventVtbl =
206 {
207 dispevent_QueryInterface,
208 dispevent_AddRef,
209 dispevent_Release,
210 dispevent_GetTypeInfoCount,
211 dispevent_GetTypeInfo,
212 dispevent_GetIDsOfNames,
213 dispevent_Invoke
214 };
215
216 static IDispatch* create_dispevent(void)
217 {
218 dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
219
220 event->IDispatch_iface.lpVtbl = &dispeventVtbl;
221 event->ref = 1;
222
223 return (IDispatch*)&event->IDispatch_iface;
224 }
225
226 /* IStream */
227 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
228 {
229 *ppvObject = NULL;
230
231 if (IsEqualGUID(riid, &IID_IStream) ||
232 IsEqualGUID(riid, &IID_IUnknown))
233 *ppvObject = iface;
234 else
235 return E_NOINTERFACE;
236
237 return S_OK;
238 }
239
240 static ULONG WINAPI istream_AddRef(IStream *iface)
241 {
242 return 2;
243 }
244
245 static ULONG WINAPI istream_Release(IStream *iface)
246 {
247 return 1;
248 }
249
250 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread)
251 {
252 ok(0, "unexpected call\n");
253 return E_NOTIMPL;
254 }
255
256 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
257 {
258 *written = len/2;
259 return S_OK;
260 }
261
262 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
263 {
264 ok(0, "unexpected call\n");
265 return E_NOTIMPL;
266 }
267
268 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size)
269 {
270 ok(0, "unexpected call\n");
271 return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len,
275 ULARGE_INTEGER *pread, ULARGE_INTEGER *written)
276 {
277 ok(0, "unexpected call\n");
278 return E_NOTIMPL;
279 }
280
281 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags)
282 {
283 ok(0, "unexpected call\n");
284 return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI istream_Revert(IStream *iface)
288 {
289 ok(0, "unexpected call\n");
290 return E_NOTIMPL;
291 }
292
293 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
294 ULARGE_INTEGER len, DWORD locktype)
295 {
296 ok(0, "unexpected call\n");
297 return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
301 ULARGE_INTEGER len, DWORD locktype)
302 {
303 ok(0, "unexpected call\n");
304 return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
308 {
309 ok(0, "unexpected call\n");
310 return E_NOTIMPL;
311 }
312
313 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream)
314 {
315 ok(0, "unexpected call\n");
316 return E_NOTIMPL;
317 }
318
319 static const IStreamVtbl StreamVtbl = {
320 istream_QueryInterface,
321 istream_AddRef,
322 istream_Release,
323 istream_Read,
324 istream_Write,
325 istream_Seek,
326 istream_SetSize,
327 istream_CopyTo,
328 istream_Commit,
329 istream_Revert,
330 istream_LockRegion,
331 istream_UnlockRegion,
332 istream_Stat,
333 istream_Clone
334 };
335
336 static IStream savestream = { &StreamVtbl };
337
338 static HRESULT WINAPI response_QI(IResponse *iface, REFIID riid, void **obj)
339 {
340 if (IsEqualIID(&IID_IResponse, riid) ||
341 IsEqualIID(&IID_IDispatch, riid) ||
342 IsEqualIID(&IID_IUnknown, riid))
343 {
344 *obj = iface;
345 return S_OK;
346 }
347
348 if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid))
349 ok(0, "unexpected call\n");
350 return E_NOINTERFACE;
351 }
352
353 static ULONG WINAPI response_AddRef(IResponse *iface)
354 {
355 return 2;
356 }
357
358 static ULONG WINAPI response_Release(IResponse *iface)
359 {
360 return 1;
361 }
362
363 static HRESULT WINAPI response_GetTypeInfoCount(IResponse *iface, UINT *count)
364 {
365 ok(0, "unexpected call\n");
366 return E_NOTIMPL;
367 }
368
369 static HRESULT WINAPI response_GetTypeInfo(IResponse *iface, UINT ti, LCID lcid, ITypeInfo **tinfo)
370 {
371 ok(0, "unexpected call\n");
372 return E_NOTIMPL;
373 }
374
375 static HRESULT WINAPI response_GetIDsOfNames(IResponse *iface, REFIID riid, LPOLESTR *names,
376 UINT cnames, LCID lcid, DISPID *rgDispId)
377 {
378 ok(0, "unexpected call\n");
379 return E_NOTIMPL;
380 }
381
382 static HRESULT WINAPI response_Invoke(IResponse *iface, DISPID dispid, REFIID riid, LCID lcid,
383 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr)
384 {
385 ok(0, "unexpected call\n");
386 return E_NOTIMPL;
387 }
388
389 static HRESULT WINAPI response_get_Buffer(IResponse *iface, VARIANT_BOOL *fIsBuffering)
390 {
391 ok(0, "unexpected call\n");
392 return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI response_put_Buffer(IResponse *iface, VARIANT_BOOL fIsBuffering)
396 {
397 ok(0, "unexpected call\n");
398 return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet)
402 {
403 ok(0, "unexpected call\n");
404 return E_NOTIMPL;
405 }
406
407 static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType)
408 {
409 ok(0, "unexpected call\n");
410 return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet)
414 {
415 ok(0, "unexpected call\n");
416 return E_NOTIMPL;
417 }
418
419 static HRESULT WINAPI response_put_Expires(IResponse *iface, LONG lExpiresMinutes)
420 {
421 ok(0, "unexpected call\n");
422 return E_NOTIMPL;
423 }
424
425 static HRESULT WINAPI response_get_ExpiresAbsolute(IResponse *iface, VARIANT *pvarExpiresRet)
426 {
427 ok(0, "unexpected call\n");
428 return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI response_put_ExpiresAbsolute(IResponse *iface, DATE dtExpires)
432 {
433 ok(0, "unexpected call\n");
434 return E_NOTIMPL;
435 }
436
437 static HRESULT WINAPI response_get_Cookies(IResponse *iface, IRequestDictionary **ppCookies)
438 {
439 ok(0, "unexpected call\n");
440 return E_NOTIMPL;
441 }
442
443 static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet)
444 {
445 ok(0, "unexpected call\n");
446 return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI response_put_Status(IResponse *iface, BSTR bstrStatus)
450 {
451 ok(0, "unexpected call\n");
452 return E_NOTIMPL;
453 }
454
455 static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName)
456 {
457 ok(0, "unexpected call\n");
458 return E_NOTIMPL;
459 }
460
461 static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue)
462 {
463 ok(0, "unexpected call\n");
464 return E_NOTIMPL;
465 }
466
467 static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry)
468 {
469 ok(0, "unexpected call\n");
470 return E_NOTIMPL;
471 }
472
473 static HRESULT WINAPI response_BinaryWrite(IResponse *iface, VARIANT input)
474 {
475 HRESULT hr;
476 LONG bound;
477 UINT dim;
478
479 ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input));
480
481 dim = SafeArrayGetDim(V_ARRAY(&input));
482 ok(dim == 1, "got wrong array dimensions %u\n", dim);
483
484 bound = 1;
485 hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound);
486 ok(hr == S_OK, "got %#x\n", hr);
487 ok(bound == 0, "wrong array low bound %d\n", bound);
488
489 bound = 0;
490 hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound);
491 ok(hr == S_OK, "got %#x\n", hr);
492 ok(bound > 0, "wrong array high bound %d\n", bound);
493
494 return E_NOTIMPL;
495 }
496
497 static HRESULT WINAPI response_Clear(IResponse *iface)
498 {
499 ok(0, "unexpected call\n");
500 return E_NOTIMPL;
501 }
502
503 static HRESULT WINAPI response_End(IResponse *iface)
504 {
505 ok(0, "unexpected call\n");
506 return E_NOTIMPL;
507 }
508
509 static HRESULT WINAPI response_Flush(IResponse *iface)
510 {
511 ok(0, "unexpected call\n");
512 return E_NOTIMPL;
513 }
514
515 static HRESULT WINAPI response_Redirect(IResponse *iface, BSTR bstrURL)
516 {
517 ok(0, "unexpected call\n");
518 return E_NOTIMPL;
519 }
520
521 static HRESULT WINAPI response_Write(IResponse *iface, VARIANT varText)
522 {
523 ok(0, "unexpected call\n");
524 return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber)
528 {
529 ok(0, "unexpected call\n");
530 return E_NOTIMPL;
531 }
532
533 static HRESULT WINAPI response_IsClientConnected(IResponse *iface, VARIANT_BOOL *pfIsClientConnected)
534 {
535 ok(0, "unexpected call\n");
536 return E_NOTIMPL;
537 }
538
539 static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet)
540 {
541 ok(0, "unexpected call\n");
542 return E_NOTIMPL;
543 }
544
545 static HRESULT WINAPI response_put_CharSet(IResponse *iface, BSTR bstrCharSet)
546 {
547 ok(0, "unexpected call\n");
548 return E_NOTIMPL;
549 }
550
551 static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue)
552 {
553 ok(0, "unexpected call\n");
554 return E_NOTIMPL;
555 }
556
557 static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl)
558 {
559 ok(0, "unexpected call\n");
560 return E_NOTIMPL;
561 }
562
563 static HRESULT WINAPI response_put_CacheControl(IResponse *iface, BSTR bstrCacheControl)
564 {
565 ok(0, "unexpected call\n");
566 return E_NOTIMPL;
567 }
568
569 static HRESULT WINAPI response_get_CodePage(IResponse *iface, LONG *plvar)
570 {
571 ok(0, "unexpected call\n");
572 return E_NOTIMPL;
573 }
574
575 static HRESULT WINAPI response_put_CodePage(IResponse *iface, LONG codepage)
576 {
577 ok(0, "unexpected call\n");
578 return E_NOTIMPL;
579 }
580
581 static HRESULT WINAPI response_get_LCID(IResponse *iface, LONG *lcid)
582 {
583 ok(0, "unexpected call\n");
584 return E_NOTIMPL;
585 }
586
587 static HRESULT WINAPI response_put_LCID(IResponse *iface, LONG lcid)
588 {
589 ok(0, "unexpected call\n");
590 return E_NOTIMPL;
591 }
592
593 static const IResponseVtbl testresponsevtbl =
594 {
595 response_QI,
596 response_AddRef,
597 response_Release,
598 response_GetTypeInfoCount,
599 response_GetTypeInfo,
600 response_GetIDsOfNames,
601 response_Invoke,
602 response_get_Buffer,
603 response_put_Buffer,
604 response_get_ContentType,
605 response_put_ContentType,
606 response_get_Expires,
607 response_put_Expires,
608 response_get_ExpiresAbsolute,
609 response_put_ExpiresAbsolute,
610 response_get_Cookies,
611 response_get_Status,
612 response_put_Status,
613 response_Add,
614 response_AddHeader,
615 response_AppendToLog,
616 response_BinaryWrite,
617 response_Clear,
618 response_End,
619 response_Flush,
620 response_Redirect,
621 response_Write,
622 response_WriteBlock,
623 response_IsClientConnected,
624 response_get_CharSet,
625 response_put_CharSet,
626 response_Pics,
627 response_get_CacheControl,
628 response_put_CacheControl,
629 response_get_CodePage,
630 response_put_CodePage,
631 response_get_LCID,
632 response_put_LCID,
633 };
634
635 static IResponse testresponse = { &testresponsevtbl };
636
637 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
638 static void _expect_children(IXMLDOMNode *node, int line)
639 {
640 VARIANT_BOOL b;
641 HRESULT hr;
642
643 b = VARIANT_FALSE;
644 hr = IXMLDOMNode_hasChildNodes(node, &b);
645 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
646 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
647 }
648
649 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
650 static void _expect_no_children(IXMLDOMNode *node, int line)
651 {
652 VARIANT_BOOL b;
653 HRESULT hr;
654
655 b = VARIANT_TRUE;
656 hr = IXMLDOMNode_hasChildNodes(node, &b);
657 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
658 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
659 }
660
661 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
662 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
663 {
664 ULONG rc;
665 IUnknown_AddRef(obj);
666 rc = IUnknown_Release(obj);
667 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
668 }
669
670 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
671 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
672 {
673 LONG length;
674 HRESULT hr;
675
676 length = 0;
677 hr = IXMLDOMNodeList_get_length(list, &length);
678 ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
679 ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
680 }
681
682 #define EXPECT_HR(hr,hr_exp) \
683 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
684
685 #define EXPECT_NOT_HR(hr,hr_exp) \
686 ok(hr != hr_exp, "got 0x%08x, expected not 0x%08x\n", hr, hr_exp)
687
688 static const WCHAR szEmpty[] = { 0 };
689 static const WCHAR szIncomplete[] = {
690 '<','?','x','m','l',' ',
691 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
692 };
693 static const WCHAR szComplete1[] = {
694 '<','?','x','m','l',' ',
695 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
696 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
697 };
698 static const WCHAR szComplete2[] = {
699 '<','?','x','m','l',' ',
700 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
701 '<','a','>','<','/','a','>','\n',0
702 };
703 static const char complete4A[] =
704 "<?xml version=\'1.0\'?>\n"
705 "<lc dl=\'str1\'>\n"
706 "<bs vr=\'str2\' sz=\'1234\'>"
707 "fn1.txt\n"
708 "</bs>\n"
709 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
710 "fn2.txt\n"
711 "</pr>\n"
712 "<empty></empty>\n"
713 "<fo>\n"
714 "<ba>\n"
715 "f1\n"
716 "</ba>\n"
717 "</fo>\n"
718 "</lc>\n";
719
720 static const WCHAR szComplete5[] = {
721 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
722 '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','"',
723 ' ','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','"','>',
724 '<','S',':','s','c','o','p','e','>',
725 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
726 '<','/','S',':','s','c','o','p','e','>',
727 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
728 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
729 'c','o','m','p','u','t','e','r',
730 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
731 '<','/','S',':','s','e','a','r','c','h','>',0
732 };
733
734 static const WCHAR szComplete6[] = {
735 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
736 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
737 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
738 };
739
740 static const char complete7[] = {
741 "<?xml version=\"1.0\"?>\n\t"
742 "<root>\n"
743 "\t<a/>\n"
744 "\t<b/>\n"
745 "\t<c/>\n"
746 "</root>"
747 };
748
749 #define DECL_WIN_1252 \
750 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
751
752 static const char win1252xml[] =
753 DECL_WIN_1252
754 "<open></open>";
755
756 static const char win1252decl[] =
757 DECL_WIN_1252
758 ;
759
760 static const char nocontent[] = "no xml content here";
761
762 static const char szExampleXML[] =
763 "<?xml version='1.0' encoding='utf-8'?>\n"
764 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
765 " <elem>\n"
766 " <a>A1 field</a>\n"
767 " <b>B1 field</b>\n"
768 " <c>C1 field</c>\n"
769 " <d>D1 field</d>\n"
770 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
771 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
772 " <![CDATA[]]> This is<strong> a</strong> <i>description</i><dot>. </dot><bar:x/>\n"
773 " </html>\n"
774 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
775 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
776 " </html>\n"
777 " </description>\n"
778 " </elem>\n"
779 "\n"
780 " <elem a='a'>\n"
781 " <a>A2 field</a>\n"
782 " <b>B2 field</b>\n"
783 " <c type=\"old\">C2 field</c>\n"
784 " <d>D2 field</d>\n"
785 " </elem>\n"
786 "\n"
787 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
788 " <a>A3 field</a>\n"
789 " <b>B3 field</b>\n"
790 " <c>C3 field</c>\n"
791 " </elem>\n"
792 "\n"
793 " <elem>\n"
794 " <a>A4 field</a>\n"
795 " <b>B4 field</b>\n"
796 " <foo:c>C4 field</foo:c>\n"
797 " <d>D4 field</d>\n"
798 " </elem>\n"
799 "</root>\n";
800
801 static const char charrefsxml[] =
802 "<?xml version='1.0'?>"
803 "<a>"
804 "<b1> Text &#65; end </b1>"
805 "<b2>&#65;&#66; &#67; </b2>"
806 "</a>";
807
808 static const CHAR szNodeTypesXML[] =
809 "<?xml version='1.0'?>"
810 "<!-- comment node 0 -->"
811 "<root id='0' depth='0'>"
812 " <!-- comment node 1 -->"
813 " text node 0"
814 " <x id='1' depth='1'>"
815 " <?foo value='PI for x'?>"
816 " <!-- comment node 2 -->"
817 " text node 1"
818 " <a id='3' depth='2'/>"
819 " <b id='4' depth='2'/>"
820 " <c id='5' depth='2'/>"
821 " </x>"
822 " <y id='2' depth='1'>"
823 " <?bar value='PI for y'?>"
824 " <!-- comment node 3 -->"
825 " text node 2"
826 " <a id='6' depth='2'/>"
827 " <b id='7' depth='2'/>"
828 " <c id='8' depth='2'/>"
829 " </y>"
830 "</root>";
831
832 static const CHAR szTransformXML[] =
833 "<?xml version=\"1.0\"?>\n"
834 "<greeting>\n"
835 "Hello World\n"
836 "</greeting>";
837
838 static const CHAR szTransformSSXML[] =
839 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
840 " <xsl:output method=\"html\"/>\n"
841 " <xsl:template match=\"/\">\n"
842 " <xsl:apply-templates select=\"greeting\"/>\n"
843 " </xsl:template>\n"
844 " <xsl:template match=\"greeting\">\n"
845 " <html>\n"
846 " <body>\n"
847 " <h1>\n"
848 " <xsl:value-of select=\".\"/>\n"
849 " </h1>\n"
850 " </body>\n"
851 " </html>\n"
852 " </xsl:template>\n"
853 "</xsl:stylesheet>";
854
855 static const CHAR szTransformOutput[] =
856 "<html><body><h1>"
857 "Hello World"
858 "</h1></body></html>";
859
860 static const CHAR szTypeValueXML[] =
861 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
862 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
863 " <string>Wine</string>\n"
864 " <string2 dt:dt=\"string\">String</string2>\n"
865 " <number dt:dt=\"number\">12.44</number>\n"
866 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
867 " <int dt:dt=\"int\">-13</int>\n"
868 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
869 " <bool dt:dt=\"boolean\">1</bool>\n"
870 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
871 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
872 " <date dt:dt=\"date\">3721-11-01</date>\n"
873 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
874 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
875 " <i1 dt:dt=\"i1\">-13</i1>\n"
876 " <i2 dt:dt=\"i2\">31915</i2>\n"
877 " <i4 dt:dt=\"i4\">-312232</i4>\n"
878 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
879 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
880 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
881 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
882 " <r8 dt:dt=\"r8\">0.412</r8>\n"
883 " <float dt:dt=\"float\">41221.421</float>\n"
884 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
885 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
886 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
887 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
888 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
889 "</root>";
890
891 static const CHAR szBasicTransformSSXMLPart1[] =
892 "<?xml version=\"1.0\"?>"
893 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
894 "<xsl:output method=\"html\"/>\n"
895 "<xsl:template match=\"/\">"
896 "<HTML><BODY><TABLE>"
897 " <xsl:apply-templates select='document(\"";
898
899 static const CHAR szBasicTransformSSXMLPart2[] =
900 "\")/bottle/wine'>"
901 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
902 " </xsl:apply-templates>"
903 "</TABLE></BODY></HTML>"
904 "</xsl:template>"
905 "<xsl:template match=\"bottle\">"
906 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
907 "</xsl:template>"
908 "<xsl:template match=\"name\">"
909 " <TD><xsl:apply-templates /></TD>"
910 "</xsl:template>"
911 "<xsl:template match=\"cost\">"
912 " <TD><xsl:apply-templates /></TD>"
913 "</xsl:template>"
914 "</xsl:stylesheet>";
915
916 static const CHAR szBasicTransformXML[] =
917 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
918
919 static const CHAR szBasicTransformOutput[] =
920 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
921
922 #define SZ_EMAIL_DTD \
923 "<!DOCTYPE email ["\
924 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
925 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
926 " <!ATTLIST email sent (yes|no) \"no\">"\
927 " <!ELEMENT recipients (to+,cc*)>"\
928 " <!ELEMENT to (#PCDATA)>"\
929 " <!ATTLIST to name CDATA #IMPLIED>"\
930 " <!ELEMENT cc (#PCDATA)>"\
931 " <!ATTLIST cc name CDATA #IMPLIED>"\
932 " <!ELEMENT from (#PCDATA)>"\
933 " <!ATTLIST from name CDATA #IMPLIED>"\
934 " <!ELEMENT reply-to (#PCDATA)>"\
935 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
936 " <!ELEMENT subject ANY>"\
937 " <!ELEMENT body ANY>"\
938 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
939 " <!ELEMENT attachment (#PCDATA)>"\
940 " <!ATTLIST attachment id ID #REQUIRED>"\
941 "]>"
942
943 static const CHAR szEmailXML[] =
944 "<?xml version=\"1.0\"?>"
945 SZ_EMAIL_DTD
946 "<email attachments=\"patch1\">"
947 " <recipients>"
948 " <to>wine-patches@winehq.org</to>"
949 " </recipients>"
950 " <from name=\"Anonymous\">user@localhost</from>"
951 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
952 " <body>"
953 " It no longer causes spontaneous combustion..."
954 " </body>"
955 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
956 "</email>";
957
958 static const CHAR szEmailXML_0D[] =
959 "<?xml version=\"1.0\"?>"
960 SZ_EMAIL_DTD
961 "<email attachments=\"patch1\">"
962 " <recipients>"
963 " <to>wine-patches@winehq.org</to>"
964 " </recipients>"
965 " <from name=\"Anonymous\">user@localhost</from>"
966 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
967 " <body>"
968 " <undecl />"
969 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
970 " </body>"
971 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
972 "</email>";
973
974 static const CHAR szEmailXML_0E[] =
975 "<?xml version=\"1.0\"?>"
976 SZ_EMAIL_DTD
977 "<email attachments=\"patch1\">"
978 " <recipients>"
979 " <to>wine-patches@winehq.org</to>"
980 " </recipients>"
981 " <from name=\"Anonymous\">user@localhost</from>"
982 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
983 " <body>"
984 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
985 " </body>"
986 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
987 "</email>";
988
989 static const CHAR szEmailXML_11[] =
990 "<?xml version=\"1.0\"?>"
991 SZ_EMAIL_DTD
992 "<email attachments=\"patch1\">"
993 " <recipients>"
994 " </recipients>"
995 " <from name=\"Anonymous\">user@localhost</from>"
996 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
997 " <body>"
998 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
999 " </body>"
1000 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1001 "</email>";
1002
1003 static const CHAR szEmailXML_13[] =
1004 "<?xml version=\"1.0\"?>"
1005 SZ_EMAIL_DTD
1006 "<msg attachments=\"patch1\">"
1007 " <recipients>"
1008 " <to>wine-patches@winehq.org</to>"
1009 " </recipients>"
1010 " <from name=\"Anonymous\">user@localhost</from>"
1011 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
1012 " <body>"
1013 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
1014 " </body>"
1015 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1016 "</msg>";
1017
1018 static const CHAR szEmailXML_14[] =
1019 "<?xml version=\"1.0\"?>"
1020 SZ_EMAIL_DTD
1021 "<email attachments=\"patch1\">"
1022 " <to>wine-patches@winehq.org</to>"
1023 " <from name=\"Anonymous\">user@localhost</from>"
1024 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
1025 " <body>"
1026 " XML_INVALID_CONTENT 0xC00CE014"
1027 " </body>"
1028 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1029 "</email>";
1030
1031 static const CHAR szEmailXML_15[] =
1032 "<?xml version=\"1.0\"?>"
1033 SZ_EMAIL_DTD
1034 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1035 " <recipients>"
1036 " <to>wine-patches@winehq.org</to>"
1037 " </recipients>"
1038 " <from name=\"Anonymous\">user@localhost</from>"
1039 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
1040 " <body>"
1041 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1042 " </body>"
1043 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1044 "</email>";
1045
1046 static const CHAR szEmailXML_16[] =
1047 "<?xml version=\"1.0\"?>"
1048 SZ_EMAIL_DTD
1049 "<email attachments=\"patch1\">"
1050 " <recipients>"
1051 " <to>wine-patches@winehq.org</to>"
1052 " </recipients>"
1053 " <from name=\"Anonymous\">user@localhost</from>"
1054 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
1055 " <body enc=\"ASCII\">"
1056 " XML_ATTRIBUTE_FIXED 0xC00CE016"
1057 " </body>"
1058 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1059 "</email>";
1060
1061 static const CHAR szEmailXML_17[] =
1062 "<?xml version=\"1.0\"?>"
1063 SZ_EMAIL_DTD
1064 "<email attachments=\"patch1\" sent=\"true\">"
1065 " <recipients>"
1066 " <to>wine-patches@winehq.org</to>"
1067 " </recipients>"
1068 " <from name=\"Anonymous\">user@localhost</from>"
1069 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
1070 " <body>"
1071 " XML_ATTRIBUTE_VALUE 0xC00CE017"
1072 " </body>"
1073 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1074 "</email>";
1075
1076 static const CHAR szEmailXML_18[] =
1077 "<?xml version=\"1.0\"?>"
1078 SZ_EMAIL_DTD
1079 "<email attachments=\"patch1\">"
1080 " oops"
1081 " <recipients>"
1082 " <to>wine-patches@winehq.org</to>"
1083 " </recipients>"
1084 " <from name=\"Anonymous\">user@localhost</from>"
1085 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
1086 " <body>"
1087 " XML_ILLEGAL_TEXT 0xC00CE018"
1088 " </body>"
1089 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1090 "</email>";
1091
1092 static const CHAR szEmailXML_20[] =
1093 "<?xml version=\"1.0\"?>"
1094 SZ_EMAIL_DTD
1095 "<email>"
1096 " <recipients>"
1097 " <to>wine-patches@winehq.org</to>"
1098 " </recipients>"
1099 " <from name=\"Anonymous\">user@localhost</from>"
1100 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
1101 " <body>"
1102 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1103 " </body>"
1104 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1105 "</email>";
1106
1107 static const char xpath_simple_list[] =
1108 "<?xml version=\"1.0\"?>"
1109 "<root>"
1110 " <a attr1=\"1\" attr2=\"2\" />"
1111 " <b/>"
1112 " <c/>"
1113 " <d/>"
1114 "</root>";
1115
1116 static const char default_ns_doc[] = {
1117 "<?xml version=\"1.0\"?>"
1118 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1119 " d=\"d attr\" />"
1120 };
1121
1122 static const char attributes_map[] = {
1123 "<?xml version=\"1.0\"?>"
1124 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1125 };
1126
1127 static const WCHAR nonexistent_fileW[] = {
1128 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1129 };
1130 static const WCHAR nonexistent_attrW[] = {
1131 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1132 };
1133 static const WCHAR szDocument[] = {
1134 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1135 };
1136
1137 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1138 static const WCHAR szdl[] = { 'd','l',0 };
1139 static const WCHAR szvr[] = { 'v','r',0 };
1140 static const WCHAR szlc[] = { 'l','c',0 };
1141 static const WCHAR szbs[] = { 'b','s',0 };
1142 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1143 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1144 static const WCHAR szstar[] = { '*',0 };
1145 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1146
1147 static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1148 static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1149 static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1150
1151 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1152 static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
1153 static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1154 static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1155 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1156 static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1157 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1158
1159 static const WCHAR szAttribute[] = {'A','t','t','r',0 };
1160 static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1161
1162 static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1163 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1164 static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1165 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1166 '!',']',']','>',0};
1167 static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1168 static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1169
1170 static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1171 static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1172 static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1173
1174 #define expect_bstr_eq_and_free(bstr, expect) { \
1175 BSTR bstrExp = alloc_str_from_narrow(expect); \
1176 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1177 SysFreeString(bstr); \
1178 SysFreeString(bstrExp); \
1179 }
1180
1181 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1182
1183 #define ole_check(expr) { \
1184 HRESULT r = expr; \
1185 ok(r == S_OK, #expr " returned %x\n", r); \
1186 }
1187
1188 #define ole_expect(expr, expect) { \
1189 HRESULT r = expr; \
1190 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1191 }
1192
1193 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1194
1195 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1196 {
1197 void *obj = NULL;
1198 HRESULT hr;
1199
1200 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1201 ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr);
1202
1203 return obj;
1204 }
1205
1206 #define _create(cls) cls, #cls
1207
1208 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1209 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1210 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1211 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1212
1213 static BSTR alloc_str_from_narrow(const char *str)
1214 {
1215 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1216 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
1217 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1218 return ret;
1219 }
1220
1221 static BSTR alloced_bstrs[256];
1222 static int alloced_bstrs_count;
1223
1224 static BSTR _bstr_(const char *str)
1225 {
1226 assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1227 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1228 return alloced_bstrs[alloced_bstrs_count++];
1229 }
1230
1231 static void free_bstrs(void)
1232 {
1233 int i;
1234 for (i = 0; i < alloced_bstrs_count; i++)
1235 SysFreeString(alloced_bstrs[i]);
1236 alloced_bstrs_count = 0;
1237 }
1238
1239 static VARIANT _variantbstr_(const char *str)
1240 {
1241 VARIANT v;
1242 V_VT(&v) = VT_BSTR;
1243 V_BSTR(&v) = _bstr_(str);
1244 return v;
1245 }
1246
1247 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1248 {
1249 for (;;)
1250 {
1251 while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1252 while (*sRight == '\r' || *sRight == '\n') sRight++;
1253 if (*sLeft != *sRight) return FALSE;
1254 if (!*sLeft) return TRUE;
1255 sLeft++;
1256 sRight++;
1257 }
1258 }
1259
1260 static void get_str_for_type(DOMNodeType type, char *buf)
1261 {
1262 switch (type)
1263 {
1264 case NODE_ATTRIBUTE:
1265 strcpy(buf, "A");
1266 break;
1267 case NODE_ELEMENT:
1268 strcpy(buf, "E");
1269 break;
1270 case NODE_DOCUMENT:
1271 strcpy(buf, "D");
1272 break;
1273 case NODE_TEXT:
1274 strcpy(buf, "T");
1275 break;
1276 case NODE_COMMENT:
1277 strcpy(buf, "C");
1278 break;
1279 case NODE_PROCESSING_INSTRUCTION:
1280 strcpy(buf, "P");
1281 break;
1282 default:
1283 wsprintfA(buf, "[%d]", type);
1284 }
1285 }
1286
1287 static int get_node_position(IXMLDOMNode *node)
1288 {
1289 HRESULT r;
1290 int pos = 0;
1291
1292 IXMLDOMNode_AddRef(node);
1293 do
1294 {
1295 IXMLDOMNode *new_node;
1296
1297 pos++;
1298 r = IXMLDOMNode_get_previousSibling(node, &new_node);
1299 ok(SUCCEEDED(r), "get_previousSibling failed\n");
1300 IXMLDOMNode_Release(node);
1301 node = new_node;
1302 } while (r == S_OK);
1303 return pos;
1304 }
1305
1306 static void node_to_string(IXMLDOMNode *node, char *buf)
1307 {
1308 HRESULT r = S_OK;
1309 DOMNodeType type;
1310
1311 if (node == NULL)
1312 {
1313 lstrcpyA(buf, "(null)");
1314 return;
1315 }
1316
1317 IXMLDOMNode_AddRef(node);
1318 while (r == S_OK)
1319 {
1320 IXMLDOMNode *new_node;
1321
1322 ole_check(IXMLDOMNode_get_nodeType(node, &type));
1323 get_str_for_type(type, buf);
1324 buf+=strlen(buf);
1325
1326 if (type == NODE_ATTRIBUTE)
1327 {
1328 BSTR bstr;
1329 ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1330 *(buf++) = '\'';
1331 wsprintfA(buf, "%ws", bstr);
1332 buf += strlen(buf);
1333 *(buf++) = '\'';
1334 SysFreeString(bstr);
1335
1336 r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1337 }
1338 else
1339 {
1340 r = IXMLDOMNode_get_parentNode(node, &new_node);
1341 sprintf(buf, "%d", get_node_position(node));
1342 buf += strlen(buf);
1343 }
1344
1345 ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1346 IXMLDOMNode_Release(node);
1347 node = new_node;
1348 if (r == S_OK)
1349 *(buf++) = '.';
1350 }
1351
1352 *buf = 0;
1353 }
1354
1355 static char *list_to_string(IXMLDOMNodeList *list)
1356 {
1357 static char buf[4096];
1358 char *pos = buf;
1359 LONG len = 0;
1360 HRESULT hr;
1361 int i;
1362
1363 if (list == NULL)
1364 {
1365 strcpy(buf, "(null)");
1366 return buf;
1367 }
1368 hr = IXMLDOMNodeList_get_length(list, &len);
1369 ok(hr == S_OK, "got 0x%08x\n", hr);
1370 for (i = 0; i < len; i++)
1371 {
1372 IXMLDOMNode *node;
1373 if (i > 0)
1374 *(pos++) = ' ';
1375 ole_check(IXMLDOMNodeList_nextNode(list, &node));
1376 node_to_string(node, pos);
1377 pos += strlen(pos);
1378 IXMLDOMNode_Release(node);
1379 }
1380 *pos = 0;
1381 return buf;
1382 }
1383
1384 #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); }
1385 #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); }
1386
1387 struct docload_ret_t {
1388 VARIANT_BOOL b;
1389 HRESULT hr;
1390 };
1391
1392 struct leading_spaces_t {
1393 const CLSID *clsid;
1394 const char *name;
1395 struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
1396 };
1397
1398 static const struct leading_spaces_t leading_spaces_classdata[] = {
1399 { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1400 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1401 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1402 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1403 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1404 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1405 { NULL }
1406 };
1407
1408 static const char* leading_spaces_xmldata[] = {
1409 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1410 " <?xml version=\"1.0\"?><root/>",
1411 "\n<?xml version=\"1.0\"?><root/>",
1412 "\t<?xml version=\"1.0\"?><root/>",
1413 "\r\n<?xml version=\"1.0\"?><root/>",
1414 "\r<?xml version=\"1.0\"?><root/>",
1415 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1416 0
1417 };
1418
1419 static void test_domdoc( void )
1420 {
1421 HRESULT r, hr;
1422 IXMLDOMDocument *doc;
1423 IXMLDOMParseError *error;
1424 IXMLDOMElement *element = NULL;
1425 IXMLDOMNode *node;
1426 IXMLDOMText *nodetext = NULL;
1427 IXMLDOMComment *node_comment = NULL;
1428 IXMLDOMAttribute *node_attr = NULL;
1429 IXMLDOMNode *nodeChild = NULL;
1430 IXMLDOMProcessingInstruction *nodePI = NULL;
1431 const struct leading_spaces_t *class_ptr;
1432 const char **data_ptr;
1433 VARIANT_BOOL b;
1434 VARIANT var;
1435 BSTR str;
1436 LONG code, ref;
1437 LONG nLength = 0;
1438 WCHAR buff[100];
1439 char path[MAX_PATH];
1440 int index;
1441
1442 GetTempPathA(MAX_PATH, path);
1443 strcat(path, "leading_spaces.xml");
1444
1445 /* Load document with leading spaces
1446 *
1447 * Test all CLSIDs with all test data XML strings
1448 */
1449 class_ptr = leading_spaces_classdata;
1450 index = 0;
1451 while (class_ptr->clsid)
1452 {
1453 HRESULT hr;
1454 int i;
1455
1456 if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
1457 {
1458 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
1459 }
1460 else
1461 {
1462 class_ptr++;
1463 index++;
1464 continue;
1465 }
1466
1467 data_ptr = leading_spaces_xmldata;
1468 i = 0;
1469 while (*data_ptr) {
1470 BSTR data = _bstr_(*data_ptr);
1471 DWORD written;
1472 HANDLE file;
1473
1474 file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1475 ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
1476
1477 WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
1478 CloseHandle(file);
1479
1480 b = 0xc;
1481 V_VT(&var) = VT_BSTR;
1482 V_BSTR(&var) = _bstr_(path);
1483 hr = IXMLDOMDocument_load(doc, var, &b);
1484 EXPECT_HR(hr, class_ptr->ret[0].hr);
1485 ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
1486
1487 DeleteFileA(path);
1488
1489 b = 0xc;
1490 hr = IXMLDOMDocument_loadXML(doc, data, &b);
1491 EXPECT_HR(hr, class_ptr->ret[1].hr);
1492 ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
1493
1494 data_ptr++;
1495 i++;
1496 }
1497
1498 class_ptr++;
1499 index++;
1500 free_bstrs();
1501 }
1502
1503 doc = create_document(&IID_IXMLDOMDocument);
1504 if (!doc) return;
1505
1506 if (0)
1507 {
1508 /* crashes on native */
1509 IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
1510 }
1511
1512 /* try some stupid things */
1513 hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1514 EXPECT_HR(hr, S_FALSE);
1515
1516 b = VARIANT_TRUE;
1517 hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
1518 EXPECT_HR(hr, S_FALSE);
1519 ok( b == VARIANT_FALSE, "failed to load XML string\n");
1520
1521 /* try to load a document from a nonexistent file */
1522 b = VARIANT_TRUE;
1523 str = SysAllocString( nonexistent_fileW );
1524 VariantInit(&var);
1525 V_VT(&var) = VT_BSTR;
1526 V_BSTR(&var) = str;
1527
1528 r = IXMLDOMDocument_load( doc, var, &b);
1529 ok( r == S_FALSE, "loadXML succeeded\n");
1530 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1531 SysFreeString( str );
1532
1533 str = (void *)0xdeadbeef;
1534 hr = IXMLDOMDocument_get_url(doc, &str);
1535 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1536 ok(str == NULL, "got %p\n", str);
1537
1538 /* try load an empty document */
1539 b = VARIANT_TRUE;
1540 str = SysAllocString( szEmpty );
1541 r = IXMLDOMDocument_loadXML( doc, str, &b );
1542 ok( r == S_FALSE, "loadXML succeeded\n");
1543 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1544 SysFreeString( str );
1545
1546 r = IXMLDOMDocument_get_async( doc, &b );
1547 ok( r == S_OK, "get_async failed (%08x)\n", r);
1548 ok( b == VARIANT_TRUE, "Wrong default value\n");
1549
1550 /* check that there's no document element */
1551 element = NULL;
1552 r = IXMLDOMDocument_get_documentElement( doc, &element );
1553 ok( r == S_FALSE, "should be no document element\n");
1554
1555 /* try finding a node */
1556 node = NULL;
1557 str = SysAllocString( szstr1 );
1558 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1559 ok( r == S_FALSE, "ret %08x\n", r );
1560 SysFreeString( str );
1561
1562 b = VARIANT_TRUE;
1563 str = SysAllocString( szIncomplete );
1564 r = IXMLDOMDocument_loadXML( doc, str, &b );
1565 ok( r == S_FALSE, "loadXML succeeded\n");
1566 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1567 SysFreeString( str );
1568
1569 /* check that there's no document element */
1570 element = (IXMLDOMElement*)1;
1571 r = IXMLDOMDocument_get_documentElement( doc, &element );
1572 ok( r == S_FALSE, "should be no document element\n");
1573 ok( element == NULL, "Element should be NULL\n");
1574
1575 /* test for BSTR handling, pass broken BSTR */
1576 memcpy(&buff[2], szComplete1, sizeof(szComplete1));
1577 /* just a big length */
1578 *(DWORD*)buff = 0xf0f0;
1579 b = VARIANT_FALSE;
1580 r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1581 ok( r == S_OK, "loadXML failed\n");
1582 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1583
1584 /* loadXML ignores the encoding attribute and always expects Unicode */
1585 b = VARIANT_FALSE;
1586 str = SysAllocString( szComplete6 );
1587 r = IXMLDOMDocument_loadXML( doc, str, &b );
1588 ok( r == S_OK, "loadXML failed\n");
1589 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1590 SysFreeString( str );
1591
1592 /* try a BSTR containing a Windows-1252 document */
1593 b = VARIANT_TRUE;
1594 str = SysAllocStringByteLen( win1252xml, strlen(win1252xml) );
1595 r = IXMLDOMDocument_loadXML( doc, str, &b );
1596 ok( r == S_FALSE, "loadXML succeeded\n");
1597 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1598 SysFreeString( str );
1599
1600 /* try to load something valid */
1601 b = VARIANT_FALSE;
1602 str = SysAllocString( szComplete1 );
1603 r = IXMLDOMDocument_loadXML( doc, str, &b );
1604 ok( r == S_OK, "loadXML failed\n");
1605 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1606 SysFreeString( str );
1607
1608 /* check if nodename is correct */
1609 r = IXMLDOMDocument_get_nodeName( doc, NULL );
1610 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1611
1612 str = (void *)0xdeadbeef;
1613 r = IXMLDOMDocument_get_baseName( doc, &str );
1614 ok ( r == S_FALSE, "got 0x%08x\n", r);
1615 ok (str == NULL, "got %p\n", str);
1616
1617 /* content doesn't matter here */
1618 str = NULL;
1619 r = IXMLDOMDocument_get_nodeName( doc, &str );
1620 ok ( r == S_OK, "get_nodeName wrong code\n");
1621 ok ( str != NULL, "str is null\n");
1622 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1623 SysFreeString( str );
1624
1625 /* test put_text */
1626 r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
1627 ok( r == E_FAIL, "ret %08x\n", r );
1628
1629 /* check that there's a document element */
1630 element = NULL;
1631 r = IXMLDOMDocument_get_documentElement( doc, &element );
1632 ok( r == S_OK, "should be a document element\n");
1633 if( element )
1634 {
1635 IObjectIdentity *ident;
1636
1637 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1638 ok( r == E_NOINTERFACE, "ret %08x\n", r);
1639
1640 IXMLDOMElement_Release( element );
1641 element = NULL;
1642 }
1643
1644 /* as soon as we call loadXML again, the document element will disappear */
1645 b = 2;
1646 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1647 ok( r == S_FALSE, "loadXML failed\n");
1648 ok( b == 2, "variant modified\n");
1649 r = IXMLDOMDocument_get_documentElement( doc, &element );
1650 ok( r == S_FALSE, "should be no document element\n");
1651
1652 /* try to load something else simple and valid */
1653 b = VARIANT_FALSE;
1654 str = SysAllocString( szComplete2 );
1655 r = IXMLDOMDocument_loadXML( doc, str, &b );
1656 ok( r == S_OK, "loadXML failed\n");
1657 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1658 SysFreeString( str );
1659
1660 /* try something a little more complicated */
1661 b = FALSE;
1662 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1663 ok( r == S_OK, "loadXML failed\n");
1664 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1665
1666 r = IXMLDOMDocument_get_parseError( doc, &error );
1667 ok( r == S_OK, "returns %08x\n", r );
1668
1669 r = IXMLDOMParseError_get_errorCode( error, &code );
1670 ok( r == S_FALSE, "returns %08x\n", r );
1671 ok( code == 0, "code %d\n", code );
1672 IXMLDOMParseError_Release( error );
1673
1674 /* test createTextNode */
1675 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1676 ok( r == S_OK, "returns %08x\n", r );
1677 IXMLDOMText_Release(nodetext);
1678
1679 str = SysAllocString( szOpen );
1680 r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1681 ok( r == E_INVALIDARG, "returns %08x\n", r );
1682 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1683 ok( r == S_OK, "returns %08x\n", r );
1684 SysFreeString( str );
1685 if(nodetext)
1686 {
1687 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1688 ok(r == E_NOINTERFACE, "ret %08x\n", r );
1689
1690 /* Text Last Child Checks */
1691 r = IXMLDOMText_get_lastChild(nodetext, NULL);
1692 ok(r == E_INVALIDARG, "ret %08x\n", r );
1693
1694 nodeChild = (IXMLDOMNode*)0x1;
1695 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1696 ok(r == S_FALSE, "ret %08x\n", r );
1697 ok(nodeChild == NULL, "nodeChild not NULL\n");
1698
1699 /* test length property */
1700 r = IXMLDOMText_get_length(nodetext, NULL);
1701 ok(r == E_INVALIDARG, "ret %08x\n", r );
1702
1703 r = IXMLDOMText_get_length(nodetext, &nLength);
1704 ok(r == S_OK, "ret %08x\n", r );
1705 ok(nLength == 4, "expected 4 got %d\n", nLength);
1706
1707 /* put data Tests */
1708 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1709 ok(r == S_OK, "ret %08x\n", r );
1710
1711 /* get data Tests */
1712 r = IXMLDOMText_get_data(nodetext, &str);
1713 ok(r == S_OK, "ret %08x\n", r );
1714 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1715 SysFreeString(str);
1716
1717 /* Confirm XML text is good */
1718 r = IXMLDOMText_get_xml(nodetext, &str);
1719 ok(r == S_OK, "ret %08x\n", r );
1720 ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
1721 SysFreeString(str);
1722
1723 /* Confirm we get the put_data Text back */
1724 r = IXMLDOMText_get_text(nodetext, &str);
1725 ok(r == S_OK, "ret %08x\n", r );
1726 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1727 SysFreeString(str);
1728
1729 /* test substringData */
1730 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1731 ok(r == E_INVALIDARG, "ret %08x\n", r );
1732
1733 /* test substringData - Invalid offset */
1734 str = (void *)0xdeadbeef;
1735 r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1736 ok(r == E_INVALIDARG, "ret %08x\n", r );
1737 ok( str == NULL, "incorrect string\n");
1738
1739 /* test substringData - Invalid offset */
1740 str = (void *)0xdeadbeef;
1741 r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1742 ok(r == S_FALSE, "ret %08x\n", r );
1743 ok( str == NULL, "incorrect string\n");
1744
1745 /* test substringData - Invalid size */
1746 str = (void *)0xdeadbeef;
1747 r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1748 ok(r == E_INVALIDARG, "ret %08x\n", r );
1749 ok( str == NULL, "incorrect string\n");
1750
1751 /* test substringData - Invalid size */
1752 str = (void *)0xdeadbeef;
1753 r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1754 ok(r == S_FALSE, "ret %08x\n", r );
1755 ok( str == NULL, "incorrect string\n");
1756
1757 /* test substringData - Start of string */
1758 r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1759 ok(r == S_OK, "ret %08x\n", r );
1760 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1761 SysFreeString(str);
1762
1763 /* test substringData - Middle of string */
1764 r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1765 ok(r == S_OK, "ret %08x\n", r );
1766 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1767 SysFreeString(str);
1768
1769 /* test substringData - End of string */
1770 r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1771 ok(r == S_OK, "ret %08x\n", r );
1772 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1773 SysFreeString(str);
1774
1775 /* test appendData */
1776 r = IXMLDOMText_appendData(nodetext, NULL);
1777 ok(r == S_OK, "ret %08x\n", r );
1778
1779 r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1780 ok(r == S_OK, "ret %08x\n", r );
1781
1782 r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1783 ok(r == S_OK, "ret %08x\n", r );
1784
1785 r = IXMLDOMText_get_text(nodetext, &str);
1786 ok(r == S_OK, "ret %08x\n", r );
1787 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1788 SysFreeString(str);
1789
1790 /* test insertData */
1791 str = SysAllocStringLen(NULL, 0);
1792 r = IXMLDOMText_insertData(nodetext, -1, str);
1793 ok(r == S_OK, "ret %08x\n", r );
1794
1795 r = IXMLDOMText_insertData(nodetext, -1, NULL);
1796 ok(r == S_OK, "ret %08x\n", r );
1797
1798 r = IXMLDOMText_insertData(nodetext, 1000, str);
1799 ok(r == S_OK, "ret %08x\n", r );
1800
1801 r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1802 ok(r == S_OK, "ret %08x\n", r );
1803
1804 r = IXMLDOMText_insertData(nodetext, 0, NULL);
1805 ok(r == S_OK, "ret %08x\n", r );
1806
1807 r = IXMLDOMText_insertData(nodetext, 0, str);
1808 ok(r == S_OK, "ret %08x\n", r );
1809 SysFreeString(str);
1810
1811 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1812 ok(r == E_INVALIDARG, "ret %08x\n", r );
1813
1814 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1815 ok(r == E_INVALIDARG, "ret %08x\n", r );
1816
1817 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1818 ok(r == S_OK, "ret %08x\n", r );
1819
1820 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1821 ok(r == S_OK, "ret %08x\n", r );
1822
1823 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1824 ok(r == S_OK, "ret %08x\n", r );
1825
1826 r = IXMLDOMText_get_text(nodetext, &str);
1827 ok(r == S_OK, "ret %08x\n", r );
1828 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1829 SysFreeString(str);
1830
1831 /* delete data */
1832 /* invalid arguments */
1833 r = IXMLDOMText_deleteData(nodetext, -1, 1);
1834 ok(r == E_INVALIDARG, "ret %08x\n", r );
1835
1836 r = IXMLDOMText_deleteData(nodetext, 0, 0);
1837 ok(r == S_OK, "ret %08x\n", r );
1838
1839 r = IXMLDOMText_deleteData(nodetext, 0, -1);
1840 ok(r == E_INVALIDARG, "ret %08x\n", r );
1841
1842 r = IXMLDOMText_get_length(nodetext, &nLength);
1843 ok(r == S_OK, "ret %08x\n", r );
1844 ok(nLength == 43, "expected 43 got %d\n", nLength);
1845
1846 r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1847 ok(r == S_OK, "ret %08x\n", r );
1848
1849 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1850 ok(r == E_INVALIDARG, "ret %08x\n", r );
1851
1852 /* delete from start */
1853 r = IXMLDOMText_deleteData(nodetext, 0, 5);
1854 ok(r == S_OK, "ret %08x\n", r );
1855
1856 r = IXMLDOMText_get_length(nodetext, &nLength);
1857 ok(r == S_OK, "ret %08x\n", r );
1858 ok(nLength == 38, "expected 38 got %d\n", nLength);
1859
1860 r = IXMLDOMText_get_text(nodetext, &str);
1861 ok(r == S_OK, "ret %08x\n", r );
1862 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1863 SysFreeString(str);
1864
1865 /* delete from end */
1866 r = IXMLDOMText_deleteData(nodetext, 35, 3);
1867 ok(r == S_OK, "ret %08x\n", r );
1868
1869 r = IXMLDOMText_get_length(nodetext, &nLength);
1870 ok(r == S_OK, "ret %08x\n", r );
1871 ok(nLength == 35, "expected 35 got %d\n", nLength);
1872
1873 r = IXMLDOMText_get_text(nodetext, &str);
1874 ok(r == S_OK, "ret %08x\n", r );
1875 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1876 SysFreeString(str);
1877
1878 /* delete from inside */
1879 r = IXMLDOMText_deleteData(nodetext, 1, 33);
1880 ok(r == S_OK, "ret %08x\n", r );
1881
1882 r = IXMLDOMText_get_length(nodetext, &nLength);
1883 ok(r == S_OK, "ret %08x\n", r );
1884 ok(nLength == 2, "expected 2 got %d\n", nLength);
1885
1886 r = IXMLDOMText_get_text(nodetext, &str);
1887 ok(r == S_OK, "ret %08x\n", r );
1888 ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1889 SysFreeString(str);
1890
1891 /* delete whole data ... */
1892 r = IXMLDOMText_get_length(nodetext, &nLength);
1893 ok(r == S_OK, "ret %08x\n", r );
1894
1895 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1896 ok(r == S_OK, "ret %08x\n", r );
1897 /* ... and try again with empty string */
1898 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1899 ok(r == S_OK, "ret %08x\n", r );
1900
1901 /* test put_data */
1902 V_VT(&var) = VT_BSTR;
1903 V_BSTR(&var) = SysAllocString(szstr1);
1904 r = IXMLDOMText_put_nodeValue(nodetext, var);
1905 ok(r == S_OK, "ret %08x\n", r );
1906 VariantClear(&var);
1907
1908 r = IXMLDOMText_get_text(nodetext, &str);
1909 ok(r == S_OK, "ret %08x\n", r );
1910 ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1911 SysFreeString(str);
1912
1913 /* test put_data */
1914 V_VT(&var) = VT_I4;
1915 V_I4(&var) = 99;
1916 r = IXMLDOMText_put_nodeValue(nodetext, var);
1917 ok(r == S_OK, "ret %08x\n", r );
1918 VariantClear(&var);
1919
1920 r = IXMLDOMText_get_text(nodetext, &str);
1921 ok(r == S_OK, "ret %08x\n", r );
1922 ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1923 SysFreeString(str);
1924
1925 /* ::replaceData() */
1926 V_VT(&var) = VT_BSTR;
1927 V_BSTR(&var) = SysAllocString(szstr1);
1928 r = IXMLDOMText_put_nodeValue(nodetext, var);
1929 ok(r == S_OK, "ret %08x\n", r );
1930 VariantClear(&var);
1931
1932 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1933 ok(r == E_INVALIDARG, "ret %08x\n", r );
1934 r = IXMLDOMText_get_text(nodetext, &str);
1935 ok(r == S_OK, "ret %08x\n", r );
1936 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1937 SysFreeString(str);
1938
1939 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1940 ok(r == S_OK, "ret %08x\n", r );
1941 r = IXMLDOMText_get_text(nodetext, &str);
1942 ok(r == S_OK, "ret %08x\n", r );
1943 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1944 SysFreeString(str);
1945
1946 /* NULL pointer means delete */
1947 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1948 ok(r == S_OK, "ret %08x\n", r );
1949 r = IXMLDOMText_get_text(nodetext, &str);
1950 ok(r == S_OK, "ret %08x\n", r );
1951 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1952 SysFreeString(str);
1953
1954 /* empty string means delete */
1955 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1956 ok(r == S_OK, "ret %08x\n", r );
1957 r = IXMLDOMText_get_text(nodetext, &str);
1958 ok(r == S_OK, "ret %08x\n", r );
1959 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1960 SysFreeString(str);
1961
1962 /* zero count means insert */
1963 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1964 ok(r == S_OK, "ret %08x\n", r );
1965 r = IXMLDOMText_get_text(nodetext, &str);
1966 ok(r == S_OK, "ret %08x\n", r );
1967 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1968 SysFreeString(str);
1969
1970 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1971 ok(r == S_OK, "ret %08x\n", r );
1972
1973 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1974 ok(r == S_OK, "ret %08x\n", r );
1975 r = IXMLDOMText_get_text(nodetext, &str);
1976 ok(r == S_OK, "ret %08x\n", r );
1977 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1978 SysFreeString(str);
1979
1980 /* nonempty string, count greater than its length */
1981 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1982 ok(r == S_OK, "ret %08x\n", r );
1983 r = IXMLDOMText_get_text(nodetext, &str);
1984 ok(r == S_OK, "ret %08x\n", r );
1985 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1986 SysFreeString(str);
1987
1988 /* nonempty string, count less than its length */
1989 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
1990 ok(r == S_OK, "ret %08x\n", r );
1991 r = IXMLDOMText_get_text(nodetext, &str);
1992 ok(r == S_OK, "ret %08x\n", r );
1993 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1994 SysFreeString(str);
1995
1996 IXMLDOMText_Release( nodetext );
1997 }
1998
1999 /* test Create Comment */
2000 r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2001 ok( r == E_INVALIDARG, "returns %08x\n", r );
2002 node_comment = (IXMLDOMComment*)0x1;
2003
2004 /* empty comment */
2005 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2006 ok( r == S_OK, "returns %08x\n", r );
2007 str = NULL;
2008 r = IXMLDOMComment_get_data(node_comment, &str);
2009 ok( r == S_OK, "returns %08x\n", r );
2010 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2011 IXMLDOMComment_Release(node_comment);
2012 SysFreeString(str);
2013
2014 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2015 ok( r == S_OK, "returns %08x\n", r );
2016 str = NULL;
2017 r = IXMLDOMComment_get_data(node_comment, &str);
2018 ok( r == S_OK, "returns %08x\n", r );
2019 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2020 IXMLDOMComment_Release(node_comment);
2021 SysFreeString(str);
2022
2023 str = SysAllocString(szComment);
2024 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2025 SysFreeString(str);
2026 ok( r == S_OK, "returns %08x\n", r );
2027 if(node_comment)
2028 {
2029 /* Last Child Checks */
2030 r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2031 ok(r == E_INVALIDARG, "ret %08x\n", r );
2032
2033 nodeChild = (IXMLDOMNode*)0x1;
2034 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2035 ok(r == S_FALSE, "ret %08x\n", r );
2036 ok(nodeChild == NULL, "pLastChild not NULL\n");
2037
2038 /* baseName */
2039 str = (void *)0xdeadbeef;
2040 r = IXMLDOMComment_get_baseName(node_comment, &str);
2041 ok(r == S_FALSE, "ret %08x\n", r );
2042 ok(str == NULL, "Expected NULL\n");
2043
2044 IXMLDOMComment_Release( node_comment );
2045 }
2046
2047 /* test Create Attribute */
2048 str = SysAllocString(szAttribute);
2049 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2050 ok( r == E_INVALIDARG, "returns %08x\n", r );
2051 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2052 ok( r == S_OK, "returns %08x\n", r );
2053 IXMLDOMAttribute_Release( node_attr);
2054 SysFreeString(str);
2055
2056 /* test Processing Instruction */
2057 str = SysAllocStringLen(NULL, 0);
2058 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2059 ok( r == E_INVALIDARG, "returns %08x\n", r );
2060 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2061 ok( r == E_FAIL, "returns %08x\n", r );
2062 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2063 ok( r == E_FAIL, "returns %08x\n", r );
2064 SysFreeString(str);
2065
2066 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2067 ok( r == S_OK, "returns %08x\n", r );
2068 if(nodePI)
2069 {
2070 /* Last Child Checks */
2071 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2072 ok(r == E_INVALIDARG, "ret %08x\n", r );
2073
2074 nodeChild = (IXMLDOMNode*)0x1;
2075 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2076 ok(r == S_FALSE, "ret %08x\n", r );
2077 ok(nodeChild == NULL, "nodeChild not NULL\n");
2078
2079 /* test nodeName */
2080 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2081 ok(r == S_OK, "ret %08x\n", r );
2082 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2083 SysFreeString(str);
2084
2085 /* test baseName */
2086 str = NULL;
2087 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2088 ok(r == S_OK, "ret %08x\n", r );
2089 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2090 SysFreeString(str);
2091
2092 /* test Target */
2093 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2094 ok(r == S_OK, "ret %08x\n", r );
2095 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2096 SysFreeString(str);
2097
2098 /* test get_data */
2099 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2100 ok(r == S_OK, "ret %08x\n", r );
2101 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2102 SysFreeString(str);
2103
2104 /* test put_data */
2105 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2106 ok(r == E_FAIL, "ret %08x\n", r );
2107
2108 /* test put_data */
2109 V_VT(&var) = VT_BSTR;
2110 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
2111 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2112 ok(r == E_FAIL, "ret %08x\n", r );
2113 VariantClear(&var);
2114
2115 /* test get nodeName */
2116 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2117 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2118 ok(r == S_OK, "ret %08x\n", r );
2119 SysFreeString(str);
2120
2121 IXMLDOMProcessingInstruction_Release(nodePI);
2122 }
2123
2124 ref = IXMLDOMDocument_Release( doc );
2125 ok( ref == 0, "got %d\n", ref);
2126
2127 free_bstrs();
2128 }
2129
2130 static void test_persiststream(void)
2131 {
2132 IPersistStreamInit *streaminit;
2133 IPersistStream *stream;
2134 IXMLDOMDocument *doc;
2135 ULARGE_INTEGER size;
2136 IPersist *persist;
2137 HRESULT hr;
2138 CLSID clsid;
2139
2140 doc = create_document(&IID_IXMLDOMDocument);
2141
2142 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2143 ok(hr == S_OK, "got 0x%08x\n", hr);
2144
2145 hr = IPersistStreamInit_InitNew(streaminit);
2146 ok(hr == S_OK, "got 0x%08x\n", hr);
2147
2148 hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
2149 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
2150
2151 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStream, (void **)&stream);
2152 ok(hr == S_OK, "got 0x%08x\n", hr);
2153 ok((IUnknown *)stream == (IUnknown *)streaminit, "got %p, %p\n", stream, streaminit);
2154
2155 hr = IPersistStream_QueryInterface(stream, &IID_IPersist, (void **)&persist);
2156 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2157
2158 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersist, (void **)&persist);
2159 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2160
2161 hr = IPersistStreamInit_GetClassID(streaminit, NULL);
2162 ok(hr == E_POINTER, "got 0x%08x\n", hr);
2163
2164 memset(&clsid, 0, sizeof(clsid));
2165 hr = IPersistStreamInit_GetClassID(streaminit, &clsid);
2166 ok(hr == S_OK, "got 0x%08x\n", hr);
2167 ok(IsEqualGUID(&clsid, &CLSID_DOMDocument2), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
2168
2169 IPersistStream_Release(stream);
2170 IPersistStreamInit_Release(streaminit);
2171 IXMLDOMDocument_Release(doc);
2172 }
2173
2174 static void test_domnode( void )
2175 {
2176 HRESULT r;
2177 IXMLDOMDocument *doc, *owner = NULL;
2178 IXMLDOMElement *element = NULL;
2179 IXMLDOMNamedNodeMap *map = NULL;
2180 IXMLDOMNode *node = NULL, *next = NULL;
2181 IXMLDOMNodeList *list = NULL;
2182 IXMLDOMAttribute *attr = NULL;
2183 DOMNodeType type = NODE_INVALID;
2184 VARIANT_BOOL b;
2185 BSTR str;
2186 VARIANT var;
2187 LONG count;
2188
2189 doc = create_document(&IID_IXMLDOMDocument);
2190
2191 b = FALSE;
2192 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2193 ok( r == S_OK, "loadXML failed\n");
2194 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2195
2196 EXPECT_CHILDREN(doc);
2197
2198 r = IXMLDOMDocument_get_documentElement( doc, &element );
2199 ok( r == S_OK, "should be a document element\n");
2200 ok( element != NULL, "should be an element\n");
2201
2202 VariantInit(&var);
2203 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2204
2205 r = IXMLDOMDocument_get_nodeValue( doc, NULL );
2206 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2207
2208 r = IXMLDOMDocument_get_nodeValue( doc, &var );
2209 ok( r == S_FALSE, "nextNode returned wrong code\n");
2210 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2211 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2212
2213 if (element)
2214 {
2215 owner = NULL;
2216 r = IXMLDOMElement_get_ownerDocument( element, &owner );
2217 ok( r == S_OK, "get_ownerDocument return code\n");
2218 ok( owner != doc, "get_ownerDocument return\n");
2219 IXMLDOMDocument_Release(owner);
2220
2221 type = NODE_INVALID;
2222 r = IXMLDOMElement_get_nodeType( element, &type);
2223 ok( r == S_OK, "got %08x\n", r);
2224 ok( type == NODE_ELEMENT, "node not an element\n");
2225
2226 str = NULL;
2227 r = IXMLDOMElement_get_baseName( element, &str );
2228 ok( r == S_OK, "get_baseName returned wrong code\n");
2229 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2230 SysFreeString(str);
2231
2232 /* check if nodename is correct */
2233 r = IXMLDOMElement_get_nodeName( element, NULL );
2234 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2235
2236 /* content doesn't matter here */
2237 str = NULL;
2238 r = IXMLDOMElement_get_nodeName( element, &str );
2239 ok ( r == S_OK, "get_nodeName wrong code\n");
2240 ok ( str != NULL, "str is null\n");
2241 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2242 SysFreeString( str );
2243
2244 str = SysAllocString( nonexistent_fileW );
2245 V_VT(&var) = VT_I4;
2246 V_I4(&var) = 0x1234;
2247 r = IXMLDOMElement_getAttribute( element, str, &var );
2248 ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2249 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2250 VariantClear(&var);
2251 SysFreeString(str);
2252
2253 str = SysAllocString( szdl );
2254 V_VT(&var) = VT_I4;
2255 V_I4(&var) = 0x1234;
2256 r = IXMLDOMElement_getAttribute( element, str, &var );
2257 ok( r == S_OK, "getAttribute ret %08x\n", r );
2258 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2259 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2260 VariantClear( &var );
2261
2262 r = IXMLDOMElement_getAttribute( element, NULL, &var );
2263 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2264
2265 r = IXMLDOMElement_getAttribute( element, str, NULL );
2266 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2267
2268 attr = NULL;
2269 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2270 ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2271 ok( attr != NULL, "getAttributeNode returned NULL\n" );
2272 if (attr)
2273 {
2274 r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2275 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2276
2277 /* attribute doesn't have a parent in msxml interpretation */
2278 node = (IXMLDOMNode*)0xdeadbeef;
2279 r = IXMLDOMAttribute_get_parentNode( attr, &node );
2280 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2281 ok( node == NULL, "Expected NULL, got %p\n", node );
2282
2283 IXMLDOMAttribute_Release(attr);
2284 }
2285
2286 SysFreeString( str );
2287
2288 r = IXMLDOMElement_get_attributes( element, &map );
2289 ok( r == S_OK, "get_attributes returned wrong code\n");
2290 ok( map != NULL, "should be attributes\n");
2291
2292 EXPECT_CHILDREN(element);
2293 }
2294 else
2295 ok( FALSE, "no element\n");
2296
2297 if (map)
2298 {
2299 str = SysAllocString( szdl );
2300 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2301 ok( r == S_OK, "getNamedItem returned wrong code\n");
2302 ok( node != NULL, "should be attributes\n");
2303 IXMLDOMNode_Release(node);
2304 SysFreeString( str );
2305
2306 str = SysAllocString( szdl );
2307 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2308 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2309 SysFreeString( str );
2310
2311 /* something that isn't in complete4A */
2312 str = SysAllocString( szOpen );
2313 node = (IXMLDOMNode *) 1;
2314 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2315 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2316 ok( node == NULL, "getNamedItem should have returned NULL\n");
2317 SysFreeString( str );
2318
2319 /* test indexed access of attributes */
2320 r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2321 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2322
2323 r = IXMLDOMNamedNodeMap_get_length( map, &count );
2324 ok ( r == S_OK, "get_length wrong code\n");
2325 ok ( count == 1, "get_length != 1\n");
2326
2327 node = NULL;
2328 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2329 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2330 ok ( node == NULL, "there is no node\n");
2331
2332 node = NULL;
2333 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2334 ok ( r == S_FALSE, "get_item (1) wrong code\n");
2335 ok ( node == NULL, "there is no attribute\n");
2336
2337 node = NULL;
2338 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2339 ok ( r == S_OK, "get_item (0) wrong code\n");
2340 ok ( node != NULL, "should be attribute\n");
2341
2342 r = IXMLDOMNode_get_nodeName( node, NULL );
2343 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2344
2345 /* content doesn't matter here */
2346 str = NULL;
2347 r = IXMLDOMNode_get_nodeName( node, &str );
2348 ok ( r == S_OK, "get_nodeName wrong code\n");
2349 ok ( str != NULL, "str is null\n");
2350 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2351 SysFreeString( str );
2352 IXMLDOMNode_Release( node );
2353
2354 /* test sequential access of attributes */
2355 node = NULL;
2356 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2357 ok ( r == S_OK, "nextNode (first time) wrong code\n");
2358 ok ( node != NULL, "nextNode, should be attribute\n");
2359 IXMLDOMNode_Release( node );
2360
2361 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2362 ok ( r != S_OK, "nextNode (second time) wrong code\n");
2363 ok ( node == NULL, "nextNode, there is no attribute\n");
2364
2365 r = IXMLDOMNamedNodeMap_reset( map );
2366 ok ( r == S_OK, "reset should return S_OK\n");
2367
2368 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2369 ok ( r == S_OK, "nextNode (third time) wrong code\n");
2370 ok ( node != NULL, "nextNode, should be attribute\n");
2371 }
2372 else
2373 ok( FALSE, "no map\n");
2374
2375 if (node)
2376 {
2377 type = NODE_INVALID;
2378 r = IXMLDOMNode_get_nodeType( node, &type);
2379 ok( r == S_OK, "getNamedItem returned wrong code\n");
2380 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2381
2382 str = NULL;
2383 r = IXMLDOMNode_get_baseName( node, NULL );
2384 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2385
2386 str = NULL;
2387 r = IXMLDOMNode_get_baseName( node, &str );
2388 ok( r == S_OK, "get_baseName returned wrong code\n");
2389 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2390 SysFreeString( str );
2391
2392 r = IXMLDOMNode_get_childNodes( node, NULL );
2393 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2394
2395 r = IXMLDOMNode_get_childNodes( node, &list );
2396 ok( r == S_OK, "get_childNodes returned wrong code\n");
2397
2398 if (list)
2399 {
2400 r = IXMLDOMNodeList_nextNode( list, &next );
2401 ok( r == S_OK, "nextNode returned wrong code\n");
2402 }
2403 else
2404 ok( FALSE, "no childlist\n");
2405
2406 if (next)
2407 {
2408 EXPECT_NO_CHILDREN(next);
2409
2410 type = NODE_INVALID;
2411 r = IXMLDOMNode_get_nodeType( next, &type);
2412 ok( r == S_OK, "getNamedItem returned wrong code\n");
2413 ok( type == NODE_TEXT, "node not text\n");
2414
2415 str = (void *)0xdeadbeef;
2416 r = IXMLDOMNode_get_baseName( next, &str );
2417 ok( r == S_FALSE, "get_baseName returned wrong code\n");
2418 ok( str == NULL, "basename was wrong\n");
2419 SysFreeString(str);
2420 }
2421 else
2422 ok( FALSE, "no next\n");
2423
2424 if (next)
2425 IXMLDOMNode_Release( next );
2426 next = NULL;
2427 if (list)
2428 IXMLDOMNodeList_Release( list );
2429 list = NULL;
2430 if (node)
2431 IXMLDOMNode_Release( node );
2432 }
2433 else
2434 ok( FALSE, "no node\n");
2435 node = NULL;
2436
2437 if (map)
2438 IXMLDOMNamedNodeMap_Release( map );
2439
2440 /* now traverse the tree from the root element */
2441 if (element)
2442 {
2443 r = IXMLDOMElement_get_childNodes( element, &list );
2444 ok( r == S_OK, "get_childNodes returned wrong code\n");
2445
2446 /* using get_item for child list doesn't advance the position */
2447 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2448 expect_node(node, "E2.E2.D1");
2449 IXMLDOMNode_Release(node);
2450 ole_check(IXMLDOMNodeList_nextNode(list, &node));
2451 expect_node(node, "E1.E2.D1");
2452 IXMLDOMNode_Release(node);
2453 ole_check(IXMLDOMNodeList_reset(list));
2454
2455 IXMLDOMNodeList_AddRef(list);
2456 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2457 ole_check(IXMLDOMNodeList_reset(list));
2458
2459 node = (void*)0xdeadbeef;
2460 str = SysAllocString(szdl);
2461 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2462 SysFreeString(str);
2463 ok( r == S_FALSE, "ret %08x\n", r );
2464 ok( node == NULL, "node %p\n", node );
2465
2466 str = SysAllocString(szbs);
2467 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2468 SysFreeString(str);
2469 ok( r == S_OK, "ret %08x\n", r );
2470 r = IXMLDOMNode_Release( node );
2471 ok( r == 0, "ret %08x\n", r );
2472 }
2473 else
2474 ok( FALSE, "no element\n");
2475
2476 if (list)
2477 {
2478 r = IXMLDOMNodeList_get_item(list, 0, NULL);
2479 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2480
2481 r = IXMLDOMNodeList_get_length(list, NULL);
2482 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2483
2484 r = IXMLDOMNodeList_get_length( list, &count );
2485 ok( r == S_OK, "get_length returns %08x\n", r );
2486 ok( count == 4, "get_length got %d\n", count );
2487
2488 r = IXMLDOMNodeList_nextNode(list, NULL);
2489 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2490
2491 r = IXMLDOMNodeList_nextNode( list, &node );
2492 ok( r == S_OK, "nextNode returned wrong code\n");
2493 }
2494 else
2495 ok( FALSE, "no list\n");
2496
2497 if (node)
2498 {
2499 type = NODE_INVALID;
2500 r = IXMLDOMNode_get_nodeType( node, &type);
2501 ok( r == S_OK, "getNamedItem returned wrong code\n");
2502 ok( type == NODE_ELEMENT, "node not text\n");
2503
2504 r = IXMLDOMNode_hasChildNodes( node, NULL );
2505 ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
2506
2507 EXPECT_CHILDREN(node);
2508
2509 str = NULL;
2510 r = IXMLDOMNode_get_baseName( node, &str );
2511 ok( r == S_OK, "get_baseName returned wrong code\n");
2512 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
2513 SysFreeString(str);
2514 }
2515 else
2516 ok( FALSE, "no node\n");
2517
2518 if (node)
2519 IXMLDOMNode_Release( node );
2520 if (list)
2521 IXMLDOMNodeList_Release( list );
2522 if (element)
2523 IXMLDOMElement_Release( element );
2524
2525 b = FALSE;
2526 str = SysAllocString( szComplete5 );
2527 r = IXMLDOMDocument_loadXML( doc, str, &b );
2528 ok( r == S_OK, "loadXML failed\n");
2529 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2530 SysFreeString( str );
2531
2532 EXPECT_CHILDREN(doc);
2533
2534 r = IXMLDOMDocument_get_documentElement( doc, &element );
2535 ok( r == S_OK, "should be a document element\n");
2536 ok( element != NULL, "should be an element\n");
2537
2538 if (element)
2539 {
2540 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
2541 BSTR tag = NULL;
2542
2543 /* check if the tag is correct */
2544 r = IXMLDOMElement_get_tagName( element, &tag );
2545 ok( r == S_OK, "couldn't get tag name\n");
2546 ok( tag != NULL, "tag was null\n");
2547 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
2548 SysFreeString( tag );
2549
2550 IXMLDOMElement_Release( element );
2551 }
2552 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2553
2554 free_bstrs();
2555 }
2556
2557 typedef struct {
2558 DOMNodeType type;
2559 REFIID iid;
2560 } refcount_test_t;
2561
2562 static const refcount_test_t refcount_test[] = {
2563 { NODE_ELEMENT, &IID_IXMLDOMElement },
2564 { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute },
2565 { NODE_TEXT, &IID_IXMLDOMText },
2566 { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection },
2567 { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference },
2568 { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
2569 { NODE_COMMENT, &IID_IXMLDOMComment },
2570 { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment },
2571 { NODE_INVALID, &IID_NULL }
2572 };
2573
2574 static void test_refs(void)
2575 {
2576 IXMLDOMImplementation *impl, *impl2;
2577 IXMLDOMElement *element, *elem2;
2578 IXMLDOMNodeList *node_list = NULL;
2579 IXMLDOMNode *node, *node2, *node3;
2580 const refcount_test_t *ptr;
2581 IXMLDOMDocument *doc;
2582 IUnknown *unk, *unk2;
2583 VARIANT_BOOL b;
2584 HRESULT hr;
2585 LONG ref;
2586
2587 doc = create_document(&IID_IXMLDOMDocument);
2588
2589 ptr = refcount_test;
2590 while (ptr->type != NODE_INVALID)
2591 {
2592 IUnknown *node_typed, *node_typed2;
2593 IDispatchEx *dispex, *dispex2;
2594 IDispatch *disp, *disp2;
2595 VARIANT type;
2596
2597 V_VT(&type) = VT_I1;
2598 V_I1(&type) = ptr->type;
2599
2600 EXPECT_REF(doc, 1);
2601 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
2602 EXPECT_HR(hr, S_OK);
2603 EXPECT_REF(doc, 1);
2604 EXPECT_REF(node, 1);
2605
2606 /* try IDispatch and IUnknown from IXMLDOMNode */
2607 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
2608 EXPECT_HR(hr, S_OK);
2609 EXPECT_REF(unk, 2);
2610 todo_wine {
2611 EXPECT_REF(node, 1);
2612 ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
2613 }
2614 EXPECT_REF(unk, 2);
2615 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2616 EXPECT_HR(hr, S_OK);
2617 todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
2618 EXPECT_REF(unk, 3);
2619 todo_wine EXPECT_REF(disp, 1);
2620
2621 EXPECT_REF(unk, 3);
2622 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
2623 EXPECT_HR(hr, S_OK);
2624 todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
2625 EXPECT_REF(unk, 4);
2626 todo_wine EXPECT_REF(disp2, 1);
2627
2628 IDispatch_Release(disp);
2629 IDispatch_Release(disp2);
2630
2631 /* get IXMLDOMNode from this IUnknown */
2632 EXPECT_REF(unk, 2);
2633 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
2634 EXPECT_HR(hr, S_OK);
2635 todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
2636 EXPECT_REF(unk, 3);
2637 todo_wine EXPECT_REF(node2, 1);
2638
2639 EXPECT_REF(unk, 3);
2640 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
2641 EXPECT_HR(hr, S_OK);
2642 todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
2643 EXPECT_REF(unk, 4);
2644 todo_wine EXPECT_REF(node3, 1);
2645
2646 IXMLDOMNode_Release(node2);
2647 IXMLDOMNode_Release(node3);
2648
2649 /* try IDispatchEx from IUnknown */
2650 EXPECT_REF(unk, 2);
2651 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
2652 EXPECT_HR(hr, S_OK);
2653 ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
2654 EXPECT_REF(unk, 3);
2655 todo_wine EXPECT_REF(dispex, 1);
2656
2657 EXPECT_REF(unk, 3);
2658 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
2659 EXPECT_HR(hr, S_OK);
2660 todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
2661 EXPECT_REF(unk, 4);
2662 todo_wine EXPECT_REF(dispex2, 1);
2663
2664 IDispatchEx_Release(dispex);
2665 IDispatchEx_Release(dispex2);
2666
2667 /* try corresponding IXMLDOM* */
2668 EXPECT_REF(unk, 2);
2669 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
2670 EXPECT_HR(hr, S_OK);
2671 EXPECT_REF(unk, 3);
2672 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
2673 EXPECT_HR(hr, S_OK);
2674 EXPECT_REF(unk, 4);
2675 todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
2676 IUnknown_Release(node_typed);
2677 IUnknown_Release(node_typed2);
2678
2679 /* try invalid IXMLDOM* */
2680 hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
2681 EXPECT_HR(hr, E_NOINTERFACE);
2682
2683 IUnknown_Release(unk);
2684
2685 EXPECT_REF(node, 1);
2686 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
2687 EXPECT_HR(hr, S_OK);
2688 EXPECT_REF(node, 2);
2689 ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
2690
2691 EXPECT_REF(node, 2);
2692 hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
2693 EXPECT_HR(hr, S_OK);
2694 EXPECT_REF(node, 3);
2695 todo_wine {
2696 EXPECT_REF(node_typed, 2);
2697 ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
2698 }
2699 IUnknown_Release(node_typed);
2700
2701 IXMLDOMNode_Release(node2);
2702 IXMLDOMNode_Release(node);
2703
2704 ptr++;
2705 }
2706
2707 EXPECT_REF(doc, 1);
2708 ref = IXMLDOMDocument_Release(doc);
2709 ok( ref == 0, "ref %d\n", ref);
2710
2711 /* check IUnknown after releasing DOM iface */
2712 doc = create_document(&IID_IXMLDOMDocument);
2713 EXPECT_REF(doc, 1);
2714 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2715 EXPECT_HR(hr, S_OK);
2716 todo_wine {
2717 EXPECT_REF(unk, 3);
2718 EXPECT_REF(doc, 1);
2719 }
2720 IXMLDOMDocument_Release(doc);
2721 EXPECT_REF(unk, 1);
2722 IUnknown_Release(unk);
2723
2724 doc = create_document(&IID_IXMLDOMDocument);
2725
2726 EXPECT_REF(doc, 1);
2727 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2728 EXPECT_HR(hr, S_OK);
2729 todo_wine {
2730 EXPECT_REF(unk, 3);
2731 EXPECT_REF(doc, 1);
2732 }
2733 IUnknown_Release(unk);
2734
2735 /* IXMLDOMImplementation */
2736 EXPECT_REF(doc, 1);
2737 hr = IXMLDOMDocument_get_implementation(doc, &impl);
2738 EXPECT_HR(hr, S_OK);
2739 EXPECT_REF(doc, 1);
2740 EXPECT_REF(impl, 1);
2741 hr = IXMLDOMDocument_get_implementation(doc, &impl2);
2742 EXPECT_HR(hr, S_OK);
2743 EXPECT_REF(doc, 1);
2744 EXPECT_REF(impl2, 1);
2745 ok(impl != impl2, "got %p, %p\n", impl, impl2);
2746 IXMLDOMImplementation_Release(impl);
2747 IXMLDOMImplementation_Release(impl2);
2748
2749 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2750 EXPECT_HR(hr, S_OK);
2751 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2752
2753 EXPECT_REF(doc, 1);
2754 IXMLDOMDocument_AddRef( doc );
2755 EXPECT_REF(doc, 2);
2756 IXMLDOMDocument_AddRef( doc );
2757 EXPECT_REF(doc, 3);
2758
2759 IXMLDOMDocument_Release( doc );
2760 IXMLDOMDocument_Release( doc );
2761
2762 EXPECT_REF(doc, 1);
2763 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2764 EXPECT_HR(hr, S_OK);
2765 todo_wine {
2766 EXPECT_REF(unk, 3);
2767 EXPECT_REF(doc, 1);
2768 }
2769 hr = IXMLDOMDocument_get_documentElement(doc, &element);
2770 EXPECT_HR(hr, S_OK);
2771 todo_wine {
2772 EXPECT_REF(doc, 1);
2773 EXPECT_REF(element, 2);
2774 }
2775 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
2776 EXPECT_HR(hr, S_OK);
2777
2778 todo_wine {
2779 EXPECT_REF(doc, 1);
2780 EXPECT_REF(element, 2);
2781 EXPECT_REF(elem2, 2);
2782 }
2783 IXMLDOMElement_AddRef(element);
2784 todo_wine EXPECT_REF(element, 3);
2785 IXMLDOMElement_Release(element);
2786
2787 /* get IUnknown from a node doesn't touch node instance refcount */
2788 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2789 EXPECT_HR(hr, S_OK);
2790 EXPECT_REF(element, 2);
2791 todo_wine {
2792 EXPECT_REF(unk, 4);
2793 EXPECT_REF(elem2, 2);
2794 }
2795 hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
2796 EXPECT_HR(hr, S_OK);
2797 todo_wine {
2798 EXPECT_REF(unk, 5);
2799 EXPECT_REF(unk2, 5);
2800 }
2801 EXPECT_REF(element, 2);
2802 EXPECT_REF(elem2, 2);
2803
2804 todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
2805 IUnknown_Release(unk);
2806
2807 /* IUnknown refcount is not affected by node refcount */
2808 todo_wine EXPECT_REF(unk2, 4);
2809 IXMLDOMElement_AddRef(elem2);
2810 todo_wine EXPECT_REF(unk2, 4);
2811 IXMLDOMElement_Release(elem2);
2812
2813 IXMLDOMElement_Release(elem2);
2814 todo_wine EXPECT_REF(unk2, 3);
2815
2816 IUnknown_Release(unk2);
2817
2818 hr = IXMLDOMElement_get_childNodes( element, &node_list );
2819 EXPECT_HR(hr, S_OK);
2820
2821 todo_wine EXPECT_REF(element, 2);
2822 EXPECT_REF(node_list, 1);
2823
2824 hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
2825 EXPECT_HR(hr, S_OK);
2826 EXPECT_REF(node_list, 1);
2827 EXPECT_REF(node, 1);
2828
2829 hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2830 EXPECT_HR(hr, S_OK);
2831 EXPECT_REF(node_list, 1);
2832 EXPECT_REF(node2, 1);
2833
2834 ref = IXMLDOMNode_Release( node );
2835 ok( ref == 0, "ref %d\n", ref );
2836 ref = IXMLDOMNode_Release( node2 );
2837 ok( ref == 0, "ref %d\n", ref );
2838
2839 ref = IXMLDOMNodeList_Release( node_list );
2840 ok( ref == 0, "ref %d\n", ref );
2841
2842 ok( node != node2, "node %p node2 %p\n", node, node2 );
2843
2844 ref = IXMLDOMDocument_Release( doc );
2845 todo_wine ok( ref == 0, "ref %d\n", ref );
2846
2847 todo_wine EXPECT_REF(element, 2);
2848
2849 /* IUnknown must be unique however we obtain it */
2850 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2851 EXPECT_HR(hr, S_OK);
2852 EXPECT_REF(element, 2);
2853 hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
2854 EXPECT_HR(hr, S_OK);
2855 todo_wine EXPECT_REF(element, 2);
2856 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2857 EXPECT_HR(hr, S_OK);
2858 todo_wine EXPECT_REF(element, 2);
2859 ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
2860 todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
2861
2862 IUnknown_Release( unk2 );
2863 IUnknown_Release( unk );
2864 IXMLDOMNode_Release( node );
2865 todo_wine EXPECT_REF(element, 2);
2866
2867 IXMLDOMElement_Release( element );
2868
2869 free_bstrs();
2870 }
2871
2872 static void test_create(void)
2873 {
2874 static const WCHAR szOne[] = {'1',0};
2875 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2876 HRESULT r;
2877 VARIANT var;
2878 BSTR str, name;
2879 IXMLDOMDocument *doc;
2880 IXMLDOMElement *element;
2881 IXMLDOMComment *comment;
2882 IXMLDOMText *text;
2883 IXMLDOMCDATASection *cdata;
2884 IXMLDOMNode *root, *node, *child;
2885 IXMLDOMNamedNodeMap *attr_map;
2886 IUnknown *unk;
2887 LONG ref;
2888 LONG num;
2889
2890 doc = create_document(&IID_IXMLDOMDocument);
2891
2892 EXPECT_REF(doc, 1);
2893
2894 /* types not supported for creation */
2895 V_VT(&var) = VT_I1;
2896 V_I1(&var) = NODE_DOCUMENT;
2897 node = (IXMLDOMNode*)0x1;
2898 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2899 ok( r == E_INVALIDARG, "returns %08x\n", r );
2900 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2901
2902 V_VT(&var) = VT_I1;
2903 V_I1(&var) = NODE_DOCUMENT_TYPE;
2904 node = (IXMLDOMNode*)0x1;
2905 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2906 ok( r == E_INVALIDARG, "returns %08x\n", r );
2907 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2908
2909 V_VT(&var) = VT_I1;
2910 V_I1(&var) = NODE_ENTITY;
2911 node = (IXMLDOMNode*)0x1;
2912 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2913 ok( r == E_INVALIDARG, "returns %08x\n", r );
2914 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2915
2916 V_VT(&var) = VT_I1;
2917 V_I1(&var) = NODE_NOTATION;
2918 node = (IXMLDOMNode*)0x1;
2919 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2920 ok( r == E_INVALIDARG, "returns %08x\n", r );
2921 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2922
2923 /* NODE_COMMENT */
2924 V_VT(&var) = VT_I1;
2925 V_I1(&var) = NODE_COMMENT;
2926 node = NULL;
2927 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2928 ok( r == S_OK, "returns %08x\n", r );
2929 ok( node != NULL, "\n");
2930
2931 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2932 ok( r == S_OK, "returns %08x\n", r );
2933 IXMLDOMNode_Release(node);
2934
2935 str = NULL;
2936 r = IXMLDOMComment_get_data(comment, &str);
2937 ok( r == S_OK, "returns %08x\n", r );
2938 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2939 IXMLDOMComment_Release(comment);
2940 SysFreeString(str);
2941
2942 node = (IXMLDOMNode*)0x1;
2943 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2944 ok( r == S_OK, "returns %08x\n", r );
2945
2946 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2947 ok( r == S_OK, "returns %08x\n", r );
2948 IXMLDOMNode_Release(node);
2949
2950 str = NULL;
2951 r = IXMLDOMComment_get_data(comment, &str);
2952 ok( r == S_OK, "returns %08x\n", r );
2953 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2954 IXMLDOMComment_Release(comment);
2955 SysFreeString(str);
2956
2957 node = (IXMLDOMNode*)0x1;
2958 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2959 ok( r == S_OK, "returns %08x\n", r );
2960
2961 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2962 ok( r == S_OK, "returns %08x\n", r );
2963 IXMLDOMNode_Release(node);
2964
2965 str = NULL;
2966 r = IXMLDOMComment_get_data(comment, &str);
2967 ok( r == S_OK, "returns %08x\n", r );
2968 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2969 IXMLDOMComment_Release(comment);
2970 SysFreeString(str);
2971
2972 /* NODE_TEXT */
2973 V_VT(&var) = VT_I1;
2974 V_I1(&var) = NODE_TEXT;
2975 node = NULL;
2976 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2977 ok( r == S_OK, "returns %08x\n", r );
2978 ok( node != NULL, "\n");
2979
2980 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2981 ok( r == S_OK, "returns %08x\n", r );
2982 IXMLDOMNode_Release(node);
2983
2984 str = NULL;
2985 r = IXMLDOMText_get_data(text, &str);
2986 ok( r == S_OK, "returns %08x\n", r );
2987 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2988 IXMLDOMText_Release(text);
2989 SysFreeString(str);
2990
2991 node = (IXMLDOMNode*)0x1;
2992 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2993 ok( r == S_OK, "returns %08x\n", r );
2994
2995 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2996 ok( r == S_OK, "returns %08x\n", r );
2997 IXMLDOMNode_Release(node);
2998
2999 str = NULL;
3000 r = IXMLDOMText_get_data(text, &str);
3001 ok( r == S_OK, "returns %08x\n", r );
3002 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3003 IXMLDOMText_Release(text);
3004 SysFreeString(str);
3005
3006 node = (IXMLDOMNode*)0x1;
3007 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3008 ok( r == S_OK, "returns %08x\n", r );
3009
3010 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3011 ok( r == S_OK, "returns %08x\n", r );
3012 IXMLDOMNode_Release(node);
3013
3014 str = NULL;
3015 r = IXMLDOMText_get_data(text, &str);
3016 ok( r == S_OK, "returns %08x\n", r );
3017 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3018 IXMLDOMText_Release(text);
3019 SysFreeString(str);
3020
3021 /* NODE_CDATA_SECTION */
3022 V_VT(&var) = VT_I1;
3023 V_I1(&var) = NODE_CDATA_SECTION;
3024 node = NULL;
3025 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3026 ok( r == S_OK, "returns %08x\n", r );
3027 ok( node != NULL, "\n");
3028
3029 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3030 ok( r == S_OK, "returns %08x\n", r );
3031 IXMLDOMNode_Release(node);
3032
3033 str = NULL;
3034 r = IXMLDOMCDATASection_get_data(cdata, &str);
3035 ok( r == S_OK, "returns %08x\n", r );
3036 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3037 IXMLDOMCDATASection_Release(cdata);
3038 SysFreeString(str);
3039
3040 node = (IXMLDOMNode*)0x1;
3041 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3042 ok( r == S_OK, "returns %08x\n", r );
3043
3044 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3045 ok( r == S_OK, "returns %08x\n", r );
3046 IXMLDOMNode_Release(node);
3047
3048 str = NULL;
3049 r = IXMLDOMCDATASection_get_data(cdata, &str);
3050 ok( r == S_OK, "returns %08x\n", r );
3051 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3052 IXMLDOMCDATASection_Release(cdata);
3053 SysFreeString(str);
3054
3055 node = (IXMLDOMNode*)0x1;
3056 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3057 ok( r == S_OK, "returns %08x\n", r );
3058
3059 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3060 ok( r == S_OK, "returns %08x\n", r );
3061 IXMLDOMNode_Release(node);
3062
3063 str = NULL;
3064 r = IXMLDOMCDATASection_get_data(cdata, &str);
3065 ok( r == S_OK, "returns %08x\n", r );
3066 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3067 IXMLDOMCDATASection_Release(cdata);
3068 SysFreeString(str);
3069
3070 /* NODE_ATTRIBUTE */
3071 V_VT(&var) = VT_I1;
3072 V_I1(&var) = NODE_ATTRIBUTE;
3073 node = (IXMLDOMNode*)0x1;
3074 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3075 ok( r == E_FAIL, "returns %08x\n", r );
3076 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3077
3078 V_VT(&var) = VT_I1;
3079 V_I1(&var) = NODE_ATTRIBUTE;
3080 node = (IXMLDOMNode*)0x1;
3081 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3082 ok( r == E_FAIL, "returns %08x\n", r );
3083 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3084
3085 V_VT(&var) = VT_I1;
3086 V_I1(&var) = NODE_ATTRIBUTE;
3087 str = SysAllocString( szlc );
3088 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3089 ok( r == S_OK, "returns %08x\n", r );
3090 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3091 SysFreeString(str);
3092
3093 /* a name is required for attribute, try a BSTR with first null wchar */
3094 V_VT(&var) = VT_I1;
3095 V_I1(&var) = NODE_ATTRIBUTE;
3096 str = SysAllocString( szstr1 );
3097 str[0] = 0;
3098 node = (IXMLDOMNode*)0x1;
3099 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3100 ok( r == E_FAIL, "returns %08x\n", r );
3101 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3102 SysFreeString(str);
3103
3104 /* NODE_PROCESSING_INSTRUCTION */
3105 V_VT(&var) = VT_I1;
3106 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3107 node = (IXMLDOMNode*)0x1;
3108 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3109 ok( r == E_FAIL, "returns %08x\n", r );
3110 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3111
3112 V_VT(&var) = VT_I1;
3113 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3114 node = (IXMLDOMNode*)0x1;
3115 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3116 ok( r == E_FAIL, "returns %08x\n", r );
3117 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3118
3119 V_VT(&var) = VT_I1;
3120 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3121 r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3122 ok( r == E_INVALIDARG, "returns %08x\n", r );
3123
3124 /* NODE_ENTITY_REFERENCE */
3125 V_VT(&var) = VT_I1;
3126 V_I1(&var) = NODE_ENTITY_REFERENCE;
3127 node = (IXMLDOMNode*)0x1;
3128 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3129 ok( r == E_FAIL, "returns %08x\n", r );
3130 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3131
3132 V_VT(&var) = VT_I1;
3133 V_I1(&var) = NODE_ENTITY_REFERENCE;
3134 node = (IXMLDOMNode*)0x1;
3135 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3136 ok( r == E_FAIL, "returns %08x\n", r );
3137 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3138
3139 /* NODE_ELEMENT */
3140 V_VT(&var) = VT_I1;
3141 V_I1(&var) = NODE_ELEMENT;
3142 node = (IXMLDOMNode*)0x1;
3143 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3144 ok( r == E_FAIL, "returns %08x\n", r );
3145 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3146
3147 V_VT(&var) = VT_I1;
3148 V_I1(&var) = NODE_ELEMENT;
3149 node = (IXMLDOMNode*)0x1;
3150 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3151 ok( r == E_FAIL, "returns %08x\n", r );
3152 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3153
3154 V_VT(&var) = VT_I1;
3155 V_I1(&var) = NODE_ELEMENT;
3156 str = SysAllocString( szlc );
3157 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3158 ok( r == S_OK, "returns %08x\n", r );
3159 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3160
3161 V_VT(&var) = VT_I1;
3162 V_I1(&var) = NODE_ELEMENT;
3163 r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3164 ok( r == E_INVALIDARG, "returns %08x\n", r );
3165
3166 V_VT(&var) = VT_R4;
3167 V_R4(&var) = NODE_ELEMENT;
3168 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3169 ok( r == S_OK, "returns %08x\n", r );
3170 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3171
3172 V_VT(&var) = VT_BSTR;
3173 V_BSTR(&var) = SysAllocString( szOne );
3174 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3175 ok( r == S_OK, "returns %08x\n", r );
3176 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3177 VariantClear(&var);
3178
3179 V_VT(&var) = VT_BSTR;
3180 V_BSTR(&var) = SysAllocString( szOneGarbage );
3181 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3182 ok( r == E_INVALIDARG, "returns %08x\n", r );
3183 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3184 VariantClear(&var);
3185
3186 V_VT(&var) = VT_I4;
3187 V_I4(&var) = NODE_ELEMENT;
3188 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3189 ok( r == S_OK, "returns %08x\n", r );
3190
3191 EXPECT_REF(doc, 1);
3192 r = IXMLDOMDocument_appendChild( doc, node, &root );
3193 ok( r == S_OK, "returns %08x\n", r );
3194 ok( node == root, "%p %p\n", node, root );
3195 EXPECT_REF(doc, 1);
3196
3197 EXPECT_REF(node, 2);
3198
3199 ref = IXMLDOMNode_Release( node );
3200 ok(ref == 1, "ref %d\n", ref);
3201 SysFreeString( str );
3202
3203 V_VT(&var) = VT_I4;
3204 V_I4(&var) = NODE_ELEMENT;
3205 str = SysAllocString( szbs );
3206 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3207 ok( r == S_OK, "returns %08x\n", r );
3208 SysFreeString( str );
3209
3210 EXPECT_REF(node, 1);
3211
3212 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3213 ok( r == S_OK, "returns %08x\n", r );
3214
3215 EXPECT_REF(unk, 2);
3216
3217 V_VT(&var) = VT_EMPTY;
3218 child = NULL;
3219 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3220 ok( r == S_OK, "returns %08x\n", r );
3221 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3222
3223 todo_wine EXPECT_REF(unk, 4);
3224
3225 IXMLDOMNode_Release( child );
3226 IUnknown_Release( unk );
3227
3228 V_VT(&var) = VT_NULL;
3229 V_DISPATCH(&var) = (IDispatch*)node;
3230 r = IXMLDOMNode_insertBefore( root, node, var, &child );
3231 ok( r == S_OK, "returns %08x\n", r );
3232 ok( node == child, "%p %p\n", node, child );
3233 IXMLDOMNode_Release( child );
3234
3235 V_VT(&var) = VT_NULL;
3236 V_DISPATCH(&var) = (IDispatch*)node;
3237 r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3238 ok( r == S_OK, "returns %08x\n", r );
3239 IXMLDOMNode_Release( node );
3240
3241 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3242 ok( r == S_OK, "returns %08x\n", r );
3243
3244 r = IXMLDOMElement_get_attributes( element, &attr_map );
3245 ok( r == S_OK, "returns %08x\n", r );
3246 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3247 ok( r == S_OK, "returns %08x\n", r );
3248 ok( num == 0, "num %d\n", num );
3249 IXMLDOMNamedNodeMap_Release( attr_map );
3250
3251 V_VT(&var) = VT_BSTR;
3252 V_BSTR(&var) = SysAllocString( szstr1 );
3253 name = SysAllocString( szdl );
3254 r = IXMLDOMElement_setAttribute( element, name, var );
3255 ok( r == S_OK, "returns %08x\n", r );
3256 r = IXMLDOMElement_get_attributes( element, &attr_map );
3257 ok( r == S_OK, "returns %08x\n", r );
3258 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3259 ok( r == S_OK, "returns %08x\n", r );
3260 ok( num == 1, "num %d\n", num );
3261 IXMLDOMNamedNodeMap_Release( attr_map );
3262 VariantClear(&var);
3263
3264 V_VT(&var) = VT_BSTR;
3265 V_BSTR(&var) = SysAllocString( szstr2 );
3266 r = IXMLDOMElement_setAttribute( element, name, var );
3267 ok( r == S_OK, "returns %08x\n", r );
3268 r = IXMLDOMElement_get_attributes( element, &attr_map );
3269 ok( r == S_OK, "returns %08x\n", r );
3270 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3271 ok( r == S_OK, "returns %08x\n", r );
3272 ok( num == 1, "num %d\n", num );
3273 IXMLDOMNamedNodeMap_Release( attr_map );
3274 VariantClear(&var);
3275 r = IXMLDOMElement_getAttribute( element, name, &var );
3276 ok( r == S_OK, "returns %08x\n", r );
3277 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3278 VariantClear(&var);
3279 SysFreeString(name);
3280
3281 V_VT(&var) = VT_BSTR;
3282 V_BSTR(&var) = SysAllocString( szstr1 );
3283 name = SysAllocString( szlc );
3284 r = IXMLDOMElement_setAttribute( element, name, var );
3285 ok( r == S_OK, "returns %08x\n", r );
3286 r = IXMLDOMElement_get_attributes( element, &attr_map );
3287 ok( r == S_OK, "returns %08x\n", r );
3288 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3289 ok( r == S_OK, "returns %08x\n", r );
3290 ok( num == 2, "num %d\n", num );
3291 IXMLDOMNamedNodeMap_Release( attr_map );
3292 VariantClear(&var);
3293 SysFreeString(name);
3294
3295 V_VT(&var) = VT_I4;
3296 V_I4(&var) = 10;
3297 name = SysAllocString( szbs );
3298 r = IXMLDOMElement_setAttribute( element, name, var );
3299 ok( r == S_OK, "returns %08x\n", r );
3300 VariantClear(&var);
3301 r = IXMLDOMElement_getAttribute( element, name, &var );
3302 ok( r == S_OK, "returns %08x\n", r );
3303 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3304 VariantClear(&var);
3305 SysFreeString(name);
3306
3307 /* Create an Attribute */
3308 V_VT(&var) = VT_I4;
3309 V_I4(&var) = NODE_ATTRIBUTE;
3310 str = SysAllocString( szAttribute );
3311 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3312 ok( r == S_OK, "returns %08x\n", r );
3313 ok( node != NULL, "node was null\n");
3314 SysFreeString(str);
3315
3316 IXMLDOMElement_Release( element );
3317 IXMLDOMNode_Release( root );
3318 IXMLDOMDocument_Release( doc );
3319 }
3320
3321 struct queryresult_t {
3322 const char *query;
3323 const char *result;
3324 int len;
3325 };
3326
3327 static const struct queryresult_t elementsbytagname[] = {
3328 { "", "P1.D1 E2.D1 E1.E2.D1 T1.E1.E2.D1 E2.E2.D1 T1.E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1 T1.E1.E4.E2.D1", 10 },
3329 { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
3330 { "bs", "E1.E2.D1", 1 },
3331 { "dl", "", 0 },
3332 { "str1","", 0 },
3333 { NULL }
3334 };
3335
3336 static void test_getElementsByTagName(void)
3337 {
3338 const struct queryresult_t *ptr = elementsbytagname;
3339 IXMLDOMNodeList *node_list;
3340 IXMLDOMDocument *doc;
3341 IXMLDOMElement *elem;
3342 WCHAR buff[100];
3343 VARIANT_BOOL b;
3344 HRESULT r;
3345 LONG len;
3346 BSTR str;
3347
3348 doc = create_document(&IID_IXMLDOMDocument);
3349
3350 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3351 ok( r == S_OK, "loadXML failed\n");
3352 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3353
3354 /* null arguments cases */
3355 r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3356 ok( r == E_INVALIDARG, "ret %08x\n", r );
3357 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL);
3358 ok( r == E_INVALIDARG, "ret %08x\n", r );
3359
3360 while (ptr->query)
3361 {
3362 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list);
3363 ok(r == S_OK, "ret %08x\n", r);
3364 r = IXMLDOMNodeList_get_length(node_list, &len);
3365 ok(r == S_OK, "ret %08x\n", r);
3366 ok(len == ptr->len, "%s: got len %d, expected %d\n", ptr->query, len, ptr->len);
3367 expect_list_and_release(node_list, ptr->result);
3368
3369 free_bstrs();
3370 ptr++;
3371 }
3372
3373 /* broken query BSTR */
3374 memcpy(&buff[2], szstar, sizeof(szstar));
3375 /* just a big length */
3376 *(DWORD*)buff = 0xf0f0;
3377 r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3378 ok( r == S_OK, "ret %08x\n", r );
3379 r = IXMLDOMNodeList_get_length( node_list, &len );
3380 ok( r == S_OK, "ret %08x\n", r );
3381 ok( len == 6, "len %d\n", len );
3382 IXMLDOMNodeList_Release( node_list );
3383
3384 /* test for element */
3385 r = IXMLDOMDocument_get_documentElement(doc, &elem);
3386 ok( r == S_OK, "ret %08x\n", r );
3387
3388 str = SysAllocString( szstar );
3389
3390 /* null arguments cases */
3391 r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3392 ok( r == E_INVALIDARG, "ret %08x\n", r );
3393 r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3394 ok( r == E_INVALIDARG, "ret %08x\n", r );
3395
3396 r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3397 ok( r == S_OK, "ret %08x\n", r );
3398 r = IXMLDOMNodeList_get_length( node_list, &len );
3399 ok( r == S_OK, "ret %08x\n", r );
3400 ok( len == 5, "len %d\n", len );
3401 expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3402 SysFreeString( str );
3403
3404 /* broken query BSTR */
3405 memcpy(&buff[2], szstar, sizeof(szstar));
3406 /* just a big length */
3407 *(DWORD*)buff = 0xf0f0;
3408 r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3409 ok( r == S_OK, "ret %08x\n", r );
3410 r = IXMLDOMNodeList_get_length( node_list, &len );
3411 ok( r == S_OK, "ret %08x\n", r );
3412 ok( len == 5, "len %d\n", len );
3413 IXMLDOMNodeList_Release( node_list );
3414
3415 IXMLDOMElement_Release(elem);
3416
3417 IXMLDOMDocument_Release( doc );
3418
3419 free_bstrs();
3420 }
3421
3422 static void test_get_text(void)
3423 {
3424 HRESULT r;
3425 BSTR str;
3426 VARIANT_BOOL b;
3427 IXMLDOMDocument *doc;
3428 IXMLDOMNode *node, *node2, *node3;
3429 IXMLDOMNode *nodeRoot;
3430 IXMLDOMNodeList *node_list;
3431 IXMLDOMNamedNodeMap *node_map;
3432 LONG len;
3433
3434 doc = create_document(&IID_IXMLDOMDocument);
3435
3436 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3437 ok( r == S_OK, "loadXML failed\n");
3438 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3439
3440 str = SysAllocString( szbs );
3441 r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3442 ok( r == S_OK, "ret %08x\n", r );
3443 SysFreeString(str);
3444
3445 /* Test to get all child node text. */
3446 r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3447 ok( r == S_OK, "ret %08x\n", r );
3448 if(r == S_OK)
3449 {
3450 r = IXMLDOMNode_get_text( nodeRoot, &str );
3451 ok( r == S_OK, "ret %08x\n", r );
3452 expect_bstr_eq_and_free(str, "fn1.txt\n \nfn2.txt\n \nf1");
3453
3454 IXMLDOMNode_Release(nodeRoot);
3455 }
3456
3457 r = IXMLDOMNodeList_get_length( node_list, NULL );
3458 ok( r == E_INVALIDARG, "ret %08x\n", r );
3459
3460 r = IXMLDOMNodeList_get_length( node_list, &len );
3461 ok( r == S_OK, "ret %08x\n", r );
3462 ok( len == 1, "expect 1 got %d\n", len );
3463
3464 r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3465 ok( r == E_INVALIDARG, "ret %08x\n", r );
3466
3467 r = IXMLDOMNodeList_nextNode( node_list, NULL );
3468 ok( r == E_INVALIDARG, "ret %08x\n", r );
3469
3470 r = IXMLDOMNodeList_get_item( node_list, 0, &node );
3471 ok( r == S_OK, "ret %08x\n", r );
3472 IXMLDOMNodeList_Release( node_list );
3473
3474 /* Invalid output parameter*/
3475 r = IXMLDOMNode_get_text( node, NULL );
3476 ok( r == E_INVALIDARG, "ret %08x\n", r );
3477
3478 r = IXMLDOMNode_get_text( node, &str );
3479 ok( r == S_OK, "ret %08x\n", r );
3480 ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
3481 SysFreeString(str);
3482
3483 r = IXMLDOMNode_get_attributes( node, &node_map );
3484 ok( r == S_OK, "ret %08x\n", r );
3485
3486 str = SysAllocString( szvr );
3487 r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3488 ok( r == S_OK, "ret %08x\n", r );
3489 SysFreeString(str);
3490
3491 r = IXMLDOMNode_get_text( node2, &str );
3492 ok( r == S_OK, "ret %08x\n", r );
3493 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3494 SysFreeString(str);
3495
3496 r = IXMLDOMNode_get_firstChild( node2, &node3 );
3497 ok( r == S_OK, "ret %08x\n", r );
3498
3499 r = IXMLDOMNode_get_text( node3, &str );
3500 ok( r == S_OK, "ret %08x\n", r );
3501 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3502 SysFreeString(str);
3503
3504
3505 IXMLDOMNode_Release( node3 );
3506 IXMLDOMNode_Release( node2 );
3507 IXMLDOMNamedNodeMap_Release( node_map );
3508 IXMLDOMNode_Release( node );
3509 IXMLDOMDocument_Release( doc );
3510
3511 free_bstrs();
3512 }
3513
3514 #ifdef __REACTOS__
3515 /*
3516 * This function is to display that xmlnodelist_QueryInterface
3517 * generates SEGV for these conditions, and once fixed make sure
3518 * it never does it again.
3519 */
3520 static void verify_nodelist_query_interface(IXMLDOMNodeList *node_list)
3521 {
3522 HRESULT hr;
3523 /*
3524 * NOTE: The following calls are supposed to test wine's
3525 * xmlnodelist_QueryInterface behaving properly.
3526 * While we should be able to expect E_POINTER (due to the NULL pointer),
3527 * it seems MS' own implementation(s) violate the spec and return
3528 * E_INVALIDARG. To not get cought be a potentially correct implementation
3529 * in the future, we check for NOT S_OK.
3530 */
3531 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, NULL);
3532 EXPECT_NOT_HR(hr, S_OK);
3533 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL);
3534 EXPECT_NOT_HR(hr, S_OK);
3535 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IXMLDOMNodeList, NULL);
3536 EXPECT_NOT_HR(hr, S_OK);
3537 }
3538 #endif
3539
3540 static void test_get_childNodes(void)
3541 {
3542 IXMLDOMNodeList *node_list, *node_list2;
3543 IEnumVARIANT *enum1, *enum2, *enum3;
3544 VARIANT_BOOL b;
3545 IXMLDOMDocument *doc;
3546 IXMLDOMNode *node, *node2;
3547 IXMLDOMElement *element;
3548 IUnknown *unk1, *unk2;
3549 HRESULT hr;
3550 VARIANT v;
3551 BSTR str;
3552 LONG len;
3553
3554 doc = create_document(&IID_IXMLDOMDocument);
3555
3556 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3557 EXPECT_HR(hr, S_OK);
3558 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3559
3560 hr = IXMLDOMDocument_get_documentElement( doc, &element );
3561 EXPECT_HR(hr, S_OK);
3562
3563 hr = IXMLDOMElement_get_childNodes( element, &node_list );
3564 EXPECT_HR(hr, S_OK);
3565
3566 #ifdef __REACTOS__
3567 verify_nodelist_query_interface(node_list);
3568 #endif
3569
3570 hr = IXMLDOMNodeList_get_length( node_list, &len );
3571 EXPECT_HR(hr, S_OK);
3572 ok( len == 4, "len %d\n", len);
3573
3574 /* refcount tests for IEnumVARIANT support */
3575 EXPECT_REF(node_list, 1);
3576 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
3577 EXPECT_HR(hr, S_OK);
3578 EXPECT_REF(node_list, 1);
3579 EXPECT_REF(enum1, 2);
3580
3581 EXPECT_REF(node_list, 1);
3582 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
3583 EXPECT_HR(hr, S_OK);
3584 EXPECT_REF(node_list, 1);
3585 ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
3586 IEnumVARIANT_Release(enum2);
3587
3588 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3589 EXPECT_HR(hr, S_OK);
3590 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
3591 EXPECT_HR(hr, S_OK);
3592 EXPECT_REF(node_list, 3);
3593 EXPECT_REF(enum1, 2);
3594 ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
3595 IUnknown_Release(unk1);
3596 IUnknown_Release(unk2);
3597
3598 EXPECT_REF(node_list, 1);
3599 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
3600 EXPECT_HR(hr, S_OK);
3601 EXPECT_REF(node_list, 2);
3602 EXPECT_REF(enum2, 1);
3603 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
3604
3605 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
3606 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3607 EXPECT_HR(hr, S_OK);
3608 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
3609 EXPECT_HR(hr, S_OK);
3610 EXPECT_REF(node_list, 3);
3611 EXPECT_REF(enum2, 2);
3612 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
3613 IUnknown_Release(unk1);
3614 IUnknown_Release(unk2);
3615
3616 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
3617 EXPECT_HR(hr, S_OK);
3618 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
3619 IEnumVARIANT_Release(enum3);
3620 IEnumVARIANT_Release(enum2);
3621
3622 /* iteration tests */
3623 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
3624 EXPECT_HR(hr, S_OK);
3625 hr = IXMLDOMNode_get_nodeName(node, &str);
3626 EXPECT_HR(hr, S_OK);
3627 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3628 SysFreeString(str);
3629 IXMLDOMNode_Release(node);
3630
3631 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3632 EXPECT_HR(hr, S_OK);
3633 hr = IXMLDOMNode_get_nodeName(node, &str);
3634 EXPECT_HR(hr, S_OK);
3635 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3636 SysFreeString(str);
3637 IXMLDOMNode_Release(node);
3638
3639 V_VT(&v) = VT_EMPTY;
3640 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
3641 EXPECT_HR(hr, S_OK);
3642 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
3643 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
3644 EXPECT_HR(hr, S_OK);
3645 hr = IXMLDOMNode_get_nodeName(node, &str);
3646 EXPECT_HR(hr, S_OK);
3647 ok(!lstrcmpW(str, _bstr_("bs")), "got node name %s\n", wine_dbgstr_w(str));
3648 SysFreeString(str);
3649 IXMLDOMNode_Release(node);
3650 VariantClear(&v);
3651
3652 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3653 EXPECT_HR(hr, S_OK);
3654 hr = IXMLDOMNode_get_nodeName(node, &str);
3655 EXPECT_HR(hr, S_OK);
3656 ok(!lstrcmpW(str, _bstr_("pr")), "got %s\n", wine_dbgstr_w(str));
3657 SysFreeString(str);
3658 IXMLDOMNode_Release(node);
3659
3660 IEnumVARIANT_Release(enum1);
3661
3662 hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3663 EXPECT_HR(hr, S_OK);
3664
3665 hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3666 EXPECT_HR(hr, S_OK);
3667
3668 hr = IXMLDOMNodeList_get_length( node_list2, &len );
3669 EXPECT_HR(hr, S_OK);
3670 ok( len == 0, "len %d\n", len);
3671
3672 hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3673 EXPECT_HR(hr, S_FALSE);
3674
3675 IXMLDOMNodeList_Release( node_list2 );
3676 IXMLDOMNode_Release( node );
3677 IXMLDOMNodeList_Release( node_list );
3678 IXMLDOMElement_Release( element );
3679
3680 /* test for children of <?xml ..?> node */
3681 hr = IXMLDOMDocument_get_firstChild(doc, &node);
3682 EXPECT_HR(hr, S_OK);
3683
3684 str = NULL;
3685 hr = IXMLDOMNode_get_nodeName(node, &str);
3686 EXPECT_HR(hr, S_OK);
3687 ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
3688 SysFreeString(str);
3689
3690 /* it returns empty but valid node list */
3691 node_list = (void*)0xdeadbeef;
3692 hr = IXMLDOMNode_get_childNodes(node, &node_list);
3693 EXPECT_HR(hr, S_OK);
3694
3695 len = -1;
3696 hr = IXMLDOMNodeList_get_length(node_list, &len);
3697 EXPECT_HR(hr, S_OK);
3698 ok(len == 0, "got %d\n", len);
3699
3700 IXMLDOMNodeList_Release( node_list );
3701 IXMLDOMNode_Release(node);
3702
3703 IXMLDOMDocument_Release( doc );
3704 free_bstrs();
3705 }
3706
3707 static void test_get_firstChild(void)
3708 {
3709 static const WCHAR xmlW[] = {'x','m','l',0};
3710 IXMLDOMDocument *doc;
3711 IXMLDOMNode *node;
3712 VARIANT_BOOL b;
3713 HRESULT r;
3714 BSTR str;
3715
3716 doc = create_document(&IID_IXMLDOMDocument);
3717
3718 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3719 ok( r == S_OK, "loadXML failed\n");
3720 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3721
3722 r = IXMLDOMDocument_get_firstChild( doc, &node );
3723 ok( r == S_OK, "ret %08x\n", r);
3724
3725 r = IXMLDOMNode_get_nodeName( node, &str );
3726 ok( r == S_OK, "ret %08x\n", r);
3727
3728 ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3729
3730 SysFreeString(str);
3731 IXMLDOMNode_Release( node );
3732 IXMLDOMDocument_Release( doc );
3733
3734 free_bstrs();
3735 }
3736
3737 static void test_get_lastChild(void)
3738 {
3739 static const WCHAR lcW[] = {'l','c',0};
3740 static const WCHAR foW[] = {'f','o',0};
3741 IXMLDOMDocument *doc;
3742 IXMLDOMNode *node, *child;
3743 VARIANT_BOOL b;
3744 HRESULT r;
3745 BSTR str;
3746
3747 doc = create_document(&IID_IXMLDOMDocument);
3748
3749 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3750 ok( r == S_OK, "loadXML failed\n");
3751 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3752
3753 r = IXMLDOMDocument_get_lastChild( doc, &node );
3754 ok( r == S_OK, "ret %08x\n", r);
3755
3756 r = IXMLDOMNode_get_nodeName( node, &str );
3757 ok( r == S_OK, "ret %08x\n", r);
3758
3759 ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
3760 SysFreeString(str);
3761
3762 r = IXMLDOMNode_get_lastChild( node, &child );
3763 ok( r == S_OK, "ret %08x\n", r);
3764
3765 r = IXMLDOMNode_get_nodeName( child, &str );
3766 ok( r == S_OK, "ret %08x\n", r);
3767
3768 ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
3769 SysFreeString(str);
3770
3771 IXMLDOMNode_Release( child );
3772 IXMLDOMNode_Release( node );
3773 IXMLDOMDocument_Release( doc );
3774
3775 free_bstrs();
3776 }
3777
3778 static void test_removeChild(void)
3779 {
3780 HRESULT r;
3781 VARIANT_BOOL b;
3782 IXMLDOMDocument *doc;
3783 IXMLDOMElement *element, *lc_element;
3784 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
3785 IXMLDOMNodeList *root_list, *fo_list;
3786
3787 doc = create_document(&IID_IXMLDOMDocument);
3788
3789 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3790 ok( r == S_OK, "loadXML failed\n");
3791 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3792
3793 r = IXMLDOMDocument_get_documentElement( doc, &element );
3794 ok( r == S_OK, "ret %08x\n", r);
3795 todo_wine EXPECT_REF(element, 2);
3796
3797 r = IXMLDOMElement_get_childNodes( element, &root_list );
3798 ok( r == S_OK, "ret %08x\n", r);
3799 EXPECT_REF(root_list, 1);
3800
3801 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3802 ok( r == S_OK, "ret %08x\n", r);
3803 EXPECT_REF(fo_node, 1);
3804
3805 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3806 ok( r == S_OK, "ret %08x\n", r);
3807 EXPECT_REF(fo_list, 1);
3808
3809 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3810 ok( r == S_OK, "ret %08x\n", r);
3811 EXPECT_REF(ba_node, 1);
3812
3813 /* invalid parameter: NULL ptr */
3814 removed_node = (void*)0xdeadbeef;
3815 r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
3816 ok( r == E_INVALIDARG, "ret %08x\n", r );
3817 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3818
3819 /* ba_node is a descendant of element, but not a direct child. */
3820 removed_node = (void*)0xdeadbeef;
3821 EXPECT_REF(ba_node, 1);
3822 EXPECT_CHILDREN(fo_node);
3823 r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
3824 ok( r == E_INVALIDARG, "ret %08x\n", r );
3825 ok( removed_node == NULL, "%p\n", removed_node );
3826 EXPECT_REF(ba_node, 1);
3827 EXPECT_CHILDREN(fo_node);
3828
3829 EXPECT_REF(ba_node, 1);
3830 EXPECT_REF(fo_node, 1);
3831 r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
3832 ok( r == S_OK, "ret %08x\n", r);
3833 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
3834 EXPECT_REF(fo_node, 2);
3835 EXPECT_REF(ba_node, 1);
3836
3837 /* try removing already removed child */
3838 temp_node = (void*)0xdeadbeef;
3839 r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
3840 ok( r == E_INVALIDARG, "ret %08x\n", r);
3841 ok( temp_node == NULL, "%p\n", temp_node );
3842 IXMLDOMNode_Release( fo_node );
3843
3844 /* the removed node has no parent anymore */
3845 r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
3846 ok( r == S_FALSE, "ret %08x\n", r);
3847 ok( temp_node == NULL, "%p\n", temp_node );
3848
3849 IXMLDOMNode_Release( removed_node );
3850 IXMLDOMNode_Release( ba_node );
3851 IXMLDOMNodeList_Release( fo_list );
3852
3853 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3854 ok( r == S_OK, "ret %08x\n", r);
3855
3856 r = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
3857 ok( r == S_OK, "ret %08x\n", r);
3858
3859 /* MS quirk: passing wrong interface pointer works, too */
3860 r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
3861 ok( r == S_OK, "ret %08x\n", r);
3862 IXMLDOMElement_Release( lc_element );
3863
3864 temp_node = (void*)0xdeadbeef;
3865 r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
3866 ok( r == S_FALSE, "ret %08x\n", r);
3867 ok( temp_node == NULL, "%p\n", temp_node );
3868
3869 IXMLDOMNode_Release( lc_node );
3870 IXMLDOMNodeList_Release( root_list );
3871 IXMLDOMElement_Release( element );
3872 IXMLDOMDocument_Release( doc );
3873
3874 free_bstrs();
3875 }
3876
3877 static void test_replaceChild(void)
3878 {
3879 HRESULT r;
3880 VARIANT_BOOL b;
3881 IXMLDOMDocument *doc;
3882 IXMLDOMElement *element, *ba_element;
3883 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
3884 IXMLDOMNodeList *root_list, *fo_list;
3885 IUnknown * unk1, *unk2;
3886 LONG len;
3887
3888 doc = create_document(&IID_IXMLDOMDocument);
3889
3890 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3891 ok( r == S_OK, "loadXML failed\n");
3892 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3893
3894 r = IXMLDOMDocument_get_documentElement( doc, &element );
3895 ok( r == S_OK, "ret %08x\n", r);
3896
3897 r = IXMLDOMElement_get_childNodes( element, &root_list );
3898 ok( r == S_OK, "ret %08x\n", r);
3899
3900 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3901 ok( r == S_OK, "ret %08x\n", r);
3902
3903 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3904 ok( r == S_OK, "ret %08x\n", r);
3905
3906 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3907 ok( r == S_OK, "ret %08x\n", r);
3908
3909 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3910 ok( r == S_OK, "ret %08x\n", r);
3911
3912 IXMLDOMNodeList_Release( fo_list );
3913
3914 /* invalid parameter: NULL ptr for element to remove */
3915 removed_node = (void*)0xdeadbeef;
3916 r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3917 ok( r == E_INVALIDARG, "ret %08x\n", r );
3918 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3919
3920 /* invalid parameter: NULL for replacement element. (Sic!) */
3921 removed_node = (void*)0xdeadbeef;
3922 r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3923 ok( r == E_INVALIDARG, "ret %08x\n", r );
3924 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3925
3926 /* invalid parameter: OldNode is not a child */
3927 removed_node = (void*)0xdeadbeef;
3928 r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3929 ok( r == E_INVALIDARG, "ret %08x\n", r );
3930 ok( removed_node == NULL, "%p\n", removed_node );
3931 IXMLDOMNode_Release( lc_node );
3932
3933 /* invalid parameter: would create loop */
3934 removed_node = (void*)0xdeadbeef;
3935 r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3936 ok( r == E_FAIL, "ret %08x\n", r );
3937 ok( removed_node == NULL, "%p\n", removed_node );
3938
3939 r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
3940 ok( r == S_OK, "ret %08x\n", r );
3941
3942 r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
3943 ok( r == S_OK, "ret %08x\n", r );
3944
3945 /* ba_node and temp_node refer to the same node, yet they
3946 are different interface pointers */
3947 ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
3948 r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
3949 ok( r == S_OK, "ret %08x\n", r );
3950 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
3951 ok( r == S_OK, "ret %08x\n", r );
3952 todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
3953
3954 IUnknown_Release( unk1 );
3955 IUnknown_Release( unk2 );
3956
3957 /* ba_node should have been removed from below fo_node */
3958 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3959 ok( r == S_OK, "ret %08x\n", r );
3960
3961 /* MS quirk: replaceChild also accepts elements instead of nodes */
3962 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
3963 ok( r == S_OK, "ret %08x\n", r );
3964 EXPECT_REF(ba_element, 2);
3965
3966 removed_node = NULL;
3967 r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
3968 ok( r == S_OK, "ret %08x\n", r );
3969 ok( removed_node != NULL, "got %p\n", removed_node);
3970 EXPECT_REF(ba_element, 3);
3971 IXMLDOMElement_Release( ba_element );
3972
3973 r = IXMLDOMNodeList_get_length( fo_list, &len);
3974 ok( r == S_OK, "ret %08x\n", r );
3975 ok( len == 0, "len %d\n", len);
3976
3977 IXMLDOMNodeList_Release( fo_list );
3978
3979 IXMLDOMNode_Release(ba_node);
3980 IXMLDOMNode_Release(fo_node);
3981 IXMLDOMNode_Release(temp_node);
3982 IXMLDOMNodeList_Release( root_list );
3983 IXMLDOMElement_Release( element );
3984 IXMLDOMDocument_Release( doc );
3985
3986 free_bstrs();
3987 }
3988
3989 static void test_removeNamedItem(void)
3990 {
3991 IXMLDOMDocument *doc;
3992 IXMLDOMElement *element;
3993 IXMLDOMNode *pr_node, *removed_node, *removed_node2;
3994 IXMLDOMNodeList *root_list;
3995 IXMLDOMNamedNodeMap * pr_attrs;
3996 VARIANT_BOOL b;
3997 BSTR str;
3998 LONG len;
3999 HRESULT r;
4000
4001 doc = create_document(&IID_IXMLDOMDocument);
4002
4003 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4004 ok( r == S_OK, "loadXML failed\n");
4005 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4006
4007 r = IXMLDOMDocument_get_documentElement( doc, &element );
4008 ok( r == S_OK, "ret %08x\n", r);
4009
4010 r = IXMLDOMElement_get_childNodes( element, &root_list );
4011 ok( r == S_OK, "ret %08x\n", r);
4012
4013 r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4014 ok( r == S_OK, "ret %08x\n", r);
4015
4016 r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4017 ok( r == S_OK, "ret %08x\n", r);
4018
4019 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4020 ok( r == S_OK, "ret %08x\n", r);
4021 ok( len == 3, "length %d\n", len);
4022
4023 removed_node = (void*)0xdeadbeef;
4024 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4025 ok ( r == E_INVALIDARG, "ret %08x\n", r);
4026 ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4027
4028 removed_node = (void*)0xdeadbeef;
4029 str = SysAllocString(szvr);
4030 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4031 ok ( r == S_OK, "ret %08x\n", r);
4032
4033 removed_node2 = (void*)0xdeadbeef;
4034 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4035 ok ( r == S_FALSE, "ret %08x\n", r);
4036 ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4037
4038 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4039 ok( r == S_OK, "ret %08x\n", r);
4040 ok( len == 2, "length %d\n", len);
4041
4042 r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4043 ok ( r == S_OK, "ret %08x\n", r);
4044 IXMLDOMNode_Release(removed_node);
4045
4046 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4047 ok( r == S_OK, "ret %08x\n", r);
4048 ok( len == 3, "length %d\n", len);
4049
4050 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4051 ok ( r == S_OK, "ret %08x\n", r);
4052
4053 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4054 ok( r == S_OK, "ret %08x\n", r);
4055 ok( len == 2, "length %d\n", len);
4056
4057 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4058 ok ( r == S_FALSE, "ret %08x\n", r);
4059
4060 SysFreeString(str);
4061
4062 IXMLDOMNamedNodeMap_Release( pr_attrs );
4063 IXMLDOMNode_Release( pr_node );
4064 IXMLDOMNodeList_Release( root_list );
4065 IXMLDOMElement_Release( element );
4066 IXMLDOMDocument_Release( doc );
4067
4068 free_bstrs();
4069 }
4070
4071 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4072 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4073 HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4074 DWORD expected2)
4075 {
4076 DWORD enabled, supported;
4077 HRESULT hr;
4078
4079 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4080 if (result == result2)
4081 ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4082 else
4083 ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4084 "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4085
4086 supported = enabled = 0xCAFECAFE;
4087 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4088 ok(hr == S_OK, "ret %08x\n", hr );
4089 if (expected == expected2)
4090 ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4091 else
4092 ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4093 "Expected %08x, got %08x\n", expected2, enabled);
4094
4095 /* reset the safety options */
4096
4097 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4098 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4099 0);
4100 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4101
4102 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4103 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4104 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4105 }
4106
4107 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4108 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4109 {
4110 DWORD enabled = 0, supported = 0;
4111 HRESULT hr;
4112
4113 /* get */
4114 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4115 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4116 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4117 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4118
4119 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4120 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4121 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4122 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4123 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4124 "got %08x\n", supported);
4125 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4126
4127 /* set -- individual flags */
4128
4129 test_IObjectSafety_set(safety, S_OK, S_OK,
4130 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4131 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4132
4133 test_IObjectSafety_set(safety, S_OK, S_OK,
4134 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4135 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4136
4137 test_IObjectSafety_set(safety, S_OK, S_OK,
4138 INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4139 0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4140
4141 /* set INTERFACE_USES_DISPEX */
4142
4143 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4144 INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4145 0, 0);
4146
4147 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4148 INTERFACE_USES_DISPEX, 0,
4149 0, 0);
4150
4151 test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4152 0, INTERFACE_USES_DISPEX,
4153 0, 0);
4154
4155 /* set option masking */
4156
4157 test_IObjectSafety_set(safety, S_OK, S_OK,
4158 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4159 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4160 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4161 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4162
4163 test_IObjectSafety_set(safety, S_OK, S_OK,
4164 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4165 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4166 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4167 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4168
4169 test_IObjectSafety_set(safety, S_OK, S_OK,
4170 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4171 INTERFACE_USES_SECURITY_MANAGER,
4172 0,
4173 0);
4174
4175 /* set -- inheriting previous settings */
4176
4177 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4178 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4179 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4180 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4181 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4182 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4183 ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4184 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4185 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4186 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4187 "got %08x\n", supported);
4188
4189 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4190 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4191 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4192 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4193 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4194 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4195 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4196 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4197 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4198 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4199 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4200 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4201 "got %08x\n", supported);
4202 }
4203
4204 static void test_IXMLDOMDocument2(void)
4205 {
4206 static const WCHAR emptyW[] = {0};
4207 IXMLDOMDocument2 *doc2, *dtddoc2;
4208 IXMLDOMDocument *doc;
4209 IXMLDOMParseError* err;
4210 IDispatchEx *dispex;
4211 VARIANT_BOOL b;
4212 VARIANT var;
4213 HRESULT r;
4214 LONG res;
4215
4216 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4217
4218 doc = create_document(&IID_IXMLDOMDocument);
4219 dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4220
4221 r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4222 ok( r == S_OK, "ret %08x\n", r );
4223 ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4224
4225 ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4226 ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4227 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4228
4229 err = NULL;
4230 ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4231 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4232 ok(err != NULL, "expected a pointer\n");
4233 if (err)
4234 {
4235 res = 0;
4236 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4237 /* XML_E_NOTWF */
4238 ok(res == E_XML_NOTWF, "got %08x\n", res);
4239 IXMLDOMParseError_Release(err);
4240 }
4241
4242 r = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b );
4243 ok( r == S_OK, "loadXML failed\n");
4244 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4245
4246 ole_check(IXMLDOMDocument_get_readyState(doc, &res));
4247 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4248
4249 err = NULL;
4250 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4251 ok(err != NULL, "expected a pointer\n");
4252 if (err)
4253 {
4254 res = 0;
4255 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4256 /* XML_E_NODTD */
4257 ok(res == E_XML_NODTD, "got %08x\n", res);
4258 IXMLDOMParseError_Release(err);
4259 }
4260
4261 r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4262 ok( r == S_OK, "ret %08x\n", r );
4263 if(r == S_OK)
4264 {
4265 IDispatchEx_Release(dispex);
4266 }
4267
4268 /* we will check if the variant got cleared */
4269 IXMLDOMDocument2_AddRef(doc2);
4270 EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4271
4272 V_VT(&var) = VT_UNKNOWN;
4273 V_UNKNOWN(&var) = (IUnknown *)doc2;
4274
4275 /* invalid calls */
4276 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
4277 expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4278 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
4279
4280 /* valid call */
4281 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4282 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4283 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4284 V_VT(&var) = VT_R4;
4285
4286 /* the variant didn't get cleared*/
4287 expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4288
4289 /* setProperty tests */
4290 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
4291 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
4292 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
4293 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4294 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4295 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4296
4297 V_VT(&var) = VT_BSTR;
4298 V_BSTR(&var) = SysAllocString(emptyW);
4299 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4300 ok(r == S_OK, "got 0x%08x\n", r);
4301 VariantClear(&var);
4302
4303 V_VT(&var) = VT_I2;
4304 V_I2(&var) = 0;
4305 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4306 ok(r == E_FAIL, "got 0x%08x\n", r);
4307
4308 /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4309 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4310 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4311 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4312
4313 IXMLDOMDocument2_Release( doc2 );
4314 IXMLDOMDocument_Release( doc );
4315
4316 /* DTD validation */
4317 ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
4318 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
4319 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4320 err = NULL;
4321 ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
4322 ok(err != NULL, "expected pointer\n");
4323 if (err)
4324 {
4325 res = 0;
4326 ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
4327 ok(res == 0, "got %08x\n", res);
4328 IXMLDOMParseError_Release(err);
4329 }
4330
4331 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
4332 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4333 err = NULL;
4334 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4335 ok(err != NULL, "expected pointer\n");
4336 if (err)
4337 {
4338 res = 0;
4339 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4340 /* XML_ELEMENT_UNDECLARED */
4341 todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
4342 IXMLDOMParseError_Release(err);
4343 }
4344
4345 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
4346 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4347 err = NULL;
4348 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4349 ok(err != NULL, "expected pointer\n");
4350 if (err)
4351 {
4352 res = 0;
4353 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4354 /* XML_ELEMENT_ID_NOT_FOUND */
4355 todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
4356 IXMLDOMParseError_Release(err);
4357 }
4358
4359 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
4360 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4361 err = NULL;
4362 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4363 ok(err != NULL, "expected pointer\n");
4364 if (err)
4365 {
4366 res = 0;
4367 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4368 /* XML_EMPTY_NOT_ALLOWED */
4369 todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
4370 IXMLDOMParseError_Release(err);
4371 }
4372
4373 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
4374 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4375 err = NULL;
4376 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4377 ok(err != NULL, "expected pointer\n");
4378 if (err)
4379 {
4380 res = 0;
4381 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4382 /* XML_ROOT_NAME_MISMATCH */
4383 todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
4384 IXMLDOMParseError_Release(err);
4385 }
4386
4387 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
4388 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4389 err = NULL;
4390 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4391 ok(err != NULL, "expected pointer\n");
4392 if (err)
4393 {
4394 res = 0;
4395 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4396 /* XML_INVALID_CONTENT */
4397 todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
4398 IXMLDOMParseError_Release(err);
4399 }
4400
4401 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
4402 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4403 err = NULL;
4404 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4405 ok(err != NULL, "expected pointer\n");
4406 if (err)
4407 {
4408 res = 0;
4409 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4410 /* XML_ATTRIBUTE_NOT_DEFINED */
4411 todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
4412 IXMLDOMParseError_Release(err);
4413 }
4414
4415 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
4416 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4417 err = NULL;
4418 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4419 ok(err != NULL, "expected pointer\n");
4420 if (err)
4421 {
4422 res = 0;
4423 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4424 /* XML_ATTRIBUTE_FIXED */
4425 todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
4426 IXMLDOMParseError_Release(err);
4427 }
4428
4429 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
4430 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4431 err = NULL;
4432 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4433 ok(err != NULL, "expected pointer\n");
4434 if (err)
4435 {
4436 res = 0;
4437 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4438 /* XML_ATTRIBUTE_VALUE */
4439 todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
4440 IXMLDOMParseError_Release(err);
4441 }
4442
4443 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
4444 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4445 err = NULL;
4446 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4447 ok(err != NULL, "expected pointer\n");
4448 if (err)
4449 {
4450 res = 0;
4451 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4452 /* XML_ILLEGAL_TEXT */
4453 todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
4454 IXMLDOMParseError_Release(err);
4455 }
4456
4457 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
4458 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4459 err = NULL;
4460 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4461 ok(err != NULL, "expected pointer\n");
4462 if (err)
4463 {
4464 res = 0;
4465 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4466 /* XML_REQUIRED_ATTRIBUTE_MISSING */
4467 todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
4468 IXMLDOMParseError_Release(err);
4469 }
4470
4471 IXMLDOMDocument2_Release( dtddoc2 );
4472 free_bstrs();
4473 }
4474
4475 #define helper_ole_check(expr) { \
4476 HRESULT r = expr; \
4477 ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
4478 }
4479
4480 #define helper_ole_check_ver(expr) { \
4481 HRESULT r = expr; \
4482 ok_(__FILE__, line)(r == S_OK, "-> %i (%s): " #expr " returned %08x\n", __LINE__, ver, r); \
4483 }
4484
4485 #define helper_expect_list_and_release(list, expstr) { \
4486 char *str = list_to_string(list); \
4487 ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i (%s): Invalid node list: %s, expected %s\n", __LINE__, ver, str, expstr); \
4488 if (list) IXMLDOMNodeList_Release(list); \
4489 }
4490
4491 #define helper_expect_bstr_and_release(bstr, str) { \
4492 ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
4493 "=> %i (%s): got %s\n", __LINE__, ver, wine_dbgstr_w(bstr)); \
4494 SysFreeString(bstr); \
4495 }
4496
4497 #define check_ws_ignored(ver, doc, str) _check_ws_ignored(__LINE__, ver, doc, str)
4498 static inline void _check_ws_ignored(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4499 {
4500 IXMLDOMNode *node1, *node2;
4501 IXMLDOMNodeList *list;
4502 BSTR bstr;
4503
4504 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4505 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4506 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4507 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4508 helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
4509
4510 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4511 helper_expect_list_and_release(list,
4512 "[4]1.E1.E5.E1.E2.D1 T2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 "
4513 "E4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1 E6.E1.E5.E1.E2.D1");
4514 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4515 if (str)
4516 {
4517 helper_expect_bstr_and_release(bstr, str);
4518 }
4519 else
4520 {
4521 helper_expect_bstr_and_release(bstr, " This is a description.");
4522 }
4523 IXMLDOMNode_Release(node1);
4524
4525 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4526 helper_expect_list_and_release(list,
4527 "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 "
4528 "E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
4529 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4530 helper_expect_bstr_and_release(bstr,
4531 "\n This is a description with preserved whitespace. \n ");
4532 IXMLDOMNode_Release(node2);
4533 }
4534
4535 #define check_ws_preserved(ver, doc, str) _check_ws_preserved(__LINE__, ver, doc, str)
4536 static inline void _check_ws_preserved(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4537 {
4538 IXMLDOMNode *node1, *node2;
4539 IXMLDOMNodeList *list;
4540 BSTR bstr;
4541
4542 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4543 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4544 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4545 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4546 helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
4547
4548 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4549 helper_expect_list_and_release(list,
4550 "T1.E2.E10.E2.E2.D1 [4]2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 "
4551 "E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 "
4552 "E7.E2.E10.E2.E2.D1 E8.E2.E10.E2.E2.D1 T9.E2.E10.E2.E2.D1");
4553 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4554 if (str)
4555 {
4556 helper_expect_bstr_and_release(bstr, str);
4557 }
4558 else
4559 {
4560 helper_expect_bstr_and_release(bstr, "\n This is a description. \n ");
4561 }
4562 IXMLDOMNode_Release(node1);
4563
4564 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4565 helper_expect_list_and_release(list,
4566 "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 "
4567 "E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
4568 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4569 helper_expect_bstr_and_release(bstr,
4570 "\n This is a description with preserved whitespace. \n ");
4571 IXMLDOMNode_Release(node2);
4572 }
4573
4574 static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
4575 {
4576 static const WCHAR b1_p[] = {' ','T','e','x','t',' ','A',' ','e','n','d',' ',0};
4577 static const WCHAR b1_i[] = {'T','e','x','t',' ','A',' ','e','n','d',0};
4578 static const WCHAR b2_p[] = {'A','B',' ','C',' ',0};
4579 static const WCHAR b2_i[] = {'A','B',' ','C',0};
4580 IXMLDOMNodeList *list;
4581 IXMLDOMElement *root;
4582 IXMLDOMNode *node;
4583 const WCHAR *text;
4584 VARIANT_BOOL b;
4585 HRESULT hr;
4586 BSTR s;
4587
4588 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, preserve);
4589 ok(hr == S_OK, "got 0x%08x\n", hr);
4590
4591 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(charrefsxml), &b);
4592 ok(hr == S_OK, "got 0x%08x\n", hr);
4593
4594 hr = IXMLDOMDocument2_get_documentElement(doc, &root);
4595 ok(hr == S_OK, "got 0x%08x\n", hr);
4596
4597 hr = IXMLDOMElement_get_childNodes(root, &list);
4598 ok(hr == S_OK, "got 0x%08x\n", hr);
4599 IXMLDOMElement_Release(root);
4600
4601 text = preserve == VARIANT_TRUE ? b1_p : b1_i;
4602 hr = IXMLDOMNodeList_get_item(list, 0, &node);
4603 ok(hr == S_OK, "got 0x%08x\n", hr);
4604 hr = IXMLDOMNode_get_text(node, &s);
4605 ok(hr == S_OK, "got 0x%08x\n", hr);
4606 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4607 SysFreeString(s);
4608 IXMLDOMNode_Release(node);
4609
4610 text = preserve == VARIANT_TRUE ? b2_p : b2_i;
4611 hr = IXMLDOMNodeList_get_item(list, 1, &node);
4612 ok(hr == S_OK, "got 0x%08x\n", hr);
4613 hr = IXMLDOMNode_get_text(node, &s);
4614 ok(hr == S_OK, "got 0x%08x\n", hr);
4615 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4616 SysFreeString(s);
4617 IXMLDOMNode_Release(node);
4618
4619 IXMLDOMNodeList_Release(list);
4620 }
4621
4622 struct whitespace_t {
4623 const CLSID *clsid;
4624 const char *name;
4625 };
4626
4627 static const struct whitespace_t whitespace_test_data[] = {
4628 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
4629 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
4630 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
4631 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
4632 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
4633 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
4634 { 0 }
4635 };
4636
4637 static void test_whitespace(void)
4638 {
4639 const struct whitespace_t *class_ptr = whitespace_test_data;
4640
4641 while (class_ptr->clsid)
4642 {
4643 IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
4644 IXMLDOMNodeList *list;
4645 IXMLDOMElement *root;
4646 VARIANT_BOOL b;
4647 HRESULT hr;
4648 LONG len;
4649
4650 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument2))
4651 {
4652 class_ptr++;
4653 continue;
4654 }
4655
4656 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4657 &IID_IXMLDOMDocument2, (void**)&doc1);
4658 ok(hr == S_OK, "got 0x%08x\n", hr);
4659
4660 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4661 &IID_IXMLDOMDocument2, (void**)&doc2);
4662 ok(hr == S_OK, "got 0x%08x\n", hr);
4663
4664 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
4665 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
4666 ok(b == VARIANT_FALSE, "expected false\n");
4667 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
4668 ok(b == VARIANT_TRUE, "expected true\n");
4669
4670 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
4671 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4672 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
4673 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4674
4675 /* switch to XPath */
4676 ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4677 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4678
4679 check_ws_ignored(class_ptr->name, doc1, NULL);
4680 check_ws_preserved(class_ptr->name, doc2, NULL);
4681
4682 /* new instances copy the property */
4683 ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
4684 ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
4685
4686 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
4687 ok(b == VARIANT_FALSE, "expected false\n");
4688 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
4689 ok(b == VARIANT_TRUE, "expected true\n");
4690
4691 check_ws_ignored(class_ptr->name, doc3, NULL);
4692 check_ws_preserved(class_ptr->name, doc4, NULL);
4693
4694 /* setting after loading xml affects trimming of leading/trailing ws only */
4695 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
4696 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
4697
4698 /* the trailing "\n " isn't there, because it was ws-only node */
4699 check_ws_ignored(class_ptr->name, doc1, " This is a description. ");
4700 check_ws_preserved(class_ptr->name, doc2, " This is a description.");
4701
4702 /* it takes effect on reload */
4703 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
4704 ok(b == VARIANT_TRUE, "expected true\n");
4705 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
4706 ok(b == VARIANT_FALSE, "expected false\n");
4707
4708 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
4709 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4710 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
4711 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4712
4713 check_ws_preserved(class_ptr->name, doc1, NULL);
4714 check_ws_ignored(class_ptr->name, doc2, NULL);
4715
4716 /* other instances follow suit */
4717 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
4718 ok(b == VARIANT_TRUE, "expected true\n");
4719 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
4720 ok(b == VARIANT_FALSE, "expected false\n");
4721
4722 check_ws_preserved(class_ptr->name, doc3, NULL);
4723 check_ws_ignored(class_ptr->name, doc4, NULL);
4724
4725 IXMLDOMDocument2_Release(doc2);
4726 IXMLDOMDocument2_Release(doc3);
4727 IXMLDOMDocument2_Release(doc4);
4728
4729 /* text with char references */
4730 test_preserve_charref(doc1, VARIANT_TRUE);
4731 test_preserve_charref(doc1, VARIANT_FALSE);
4732
4733 /* formatting whitespaces */
4734 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
4735 ok(hr == S_OK, "got 0x%08x\n", hr);
4736
4737 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
4738 ok(hr == S_OK, "got 0x%08x\n", hr);
4739 ok(b == VARIANT_TRUE, "for %x\n", b);
4740
4741 hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
4742 ok(hr == S_OK, "got 0x%08x\n", hr);
4743 hr = IXMLDOMElement_get_childNodes(root, &list);
4744 ok(hr == S_OK, "got 0x%08x\n", hr);
4745 len = 0;
4746 hr = IXMLDOMNodeList_get_length(list, &len);
4747 ok(hr == S_OK, "got 0x%08x\n", hr);
4748 ok(len == 3, "got %d\n", len);
4749 IXMLDOMNodeList_Release(list);
4750 IXMLDOMElement_Release(root);
4751
4752 IXMLDOMDocument2_Release(doc1);
4753
4754 free_bstrs();
4755
4756 class_ptr++;
4757 }
4758 }
4759
4760 typedef struct {
4761 const GUID *clsid;
4762 const char *name;
4763 const char *ns;
4764 HRESULT hr;
4765 } selection_ns_t;
4766
4767 /* supposed to be tested with szExampleXML */
4768 static const selection_ns_t selection_ns_data[] = {
4769 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4770 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4771 { &CLSID_DOMDocument, "CLSID_DOMDocument", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4772 { &CLSID_DOMDocument, "CLSID_DOMDocument", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4773
4774 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4775 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4776 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4777 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4778
4779 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4780 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4781 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4782 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4783
4784 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4785 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4786 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4787 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4788
4789 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4790 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4791 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4792 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4793
4794 { NULL }
4795 };
4796
4797 typedef struct {
4798 const char *query;
4799 const char *list;
4800 } xpath_test_t;
4801
4802 static const xpath_test_t xpath_test[] = {
4803 { "*/a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4804 { "*/b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4805 { "*/c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4806 { "*/d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4807 { "//a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4808 { "//b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4809 { "//c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4810 { "//d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4811 { "//c[@type]", "E3.E2.E2.D1" },
4812 { "//c[@type]/ancestor::node()[1]", "E2.E2.D1" },
4813 { "//c[@type]/ancestor-or-self::node()[1]", "E3.E2.E2.D1" },
4814 { "//c[@type]/attribute::node()[1]", "A'type'.E3.E2.E2.D1" },
4815 { "//c[@type]/child::node()[1]", "T1.E3.E2.E2.D1" },
4816 { "//c[@type]/descendant::node()[1]", "T1.E3.E2.E2.D1" },
4817 { "//c[@type]/descendant-or-self::node()[1]", "E3.E2.E2.D1" },
4818 { "//c[@type]/following::node()[1]", "E4.E2.E2.D1" },
4819 { "//c[@type]/following-sibling::node()[1]", "E4.E2.E2.D1" },
4820 { "//c[@type]/parent::node()[1]", "E2.E2.D1" },
4821 { "//c[@type]/preceding::node()[1]", "T1.E2.E2.E2.D1" },
4822 { "//c[@type]/self::node()[1]", "E3.E2.E2.D1" },
4823 { "child::*", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4824 { "child::node()", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4825 { "child::text()", "" },
4826 { "child::*/..", "E2.D1" },
4827 { "child::*//@*/..", "E2.E5.E1.E2.D1 E2.E2.D1 E3.E2.E2.D1" },
4828 { "self::node()", "E2.D1" },
4829 { "ancestor::node()", "D1" },
4830 { "elem[c][last()]/a", "E1.E2.E2.D1"},
4831 { "ancestor-or-self::node()[1]", "E2.D1" },
4832 { "((//a)[1])[last()]", "E1.E1.E2.D1" },
4833 { "//elem[@*]", "E2.E2.D1" },
4834 { NULL }
4835 };
4836
4837 static void test_XPath(void)
4838 {
4839 const selection_ns_t *ptr = selection_ns_data;
4840 const xpath_test_t *xptest = xpath_test;
4841 VARIANT var;
4842 VARIANT_BOOL b;
4843 IXMLDOMDocument2 *doc;
4844 IXMLDOMDocument *doc2;
4845 IXMLDOMNode *rootNode;
4846 IXMLDOMNode *elem1Node;
4847 IXMLDOMNode *node;
4848 IXMLDOMNodeList *list;
4849 IXMLDOMElement *elem;
4850 IXMLDOMAttribute *attr;
4851 DOMNodeType type;
4852 HRESULT hr;
4853 LONG len;
4854 BSTR str;
4855
4856 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4857 doc = create_document(&IID_IXMLDOMDocument2);
4858
4859 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
4860 EXPECT_HR(hr, S_OK);
4861 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4862
4863 /* switch to XPath */
4864 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4865
4866 /* some simple queries*/
4867 EXPECT_REF(doc, 1);
4868 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4869 EXPECT_HR(hr, S_OK);
4870 EXPECT_REF(doc, 1);
4871 EXPECT_LIST_LEN(list, 1);
4872
4873 EXPECT_REF(list, 1);
4874 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4875 EXPECT_HR(hr, S_OK);
4876 EXPECT_REF(list, 1);
4877 EXPECT_REF(rootNode, 1);
4878
4879 hr = IXMLDOMNodeList_reset(list);
4880 EXPECT_HR(hr, S_OK);
4881 expect_list_and_release(list, "E2.D1");
4882
4883 /* peform xpath tests */
4884 for ( ; xptest->query ; xptest++ )
4885 {
4886 char *str;
4887
4888 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(xptest->query), &list);
4889 ok(hr == S_OK, "query evaluation failed for query=%s\n", xptest->query);
4890
4891 if (hr != S_OK)
4892 continue;
4893
4894 str = list_to_string(list);
4895
4896 ok(!strcmp(str, xptest->list), "query=%s, invalid node list: \"%s\", expected \"%s\"\n",
4897 xptest->query, str, xptest->list);
4898
4899 if (list)
4900 IXMLDOMNodeList_Release(list);
4901 }
4902
4903 if (0)
4904 {
4905 /* namespace:: axis test is disabled until namespace definitions
4906 are supported as attribute nodes, currently it's another node type */
4907 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
4908 EXPECT_HR(hr, S_OK);
4909 len = -1;
4910 hr = IXMLDOMNodeList_get_length(list, &len);
4911 EXPECT_HR(hr, S_OK);
4912 ok(len == 2, "got %d\n", len);
4913
4914 hr = IXMLDOMNodeList_nextNode(list, &node);
4915 EXPECT_HR(hr, S_OK);
4916 type = NODE_INVALID;
4917 hr = IXMLDOMNode_get_nodeType(node, &type);
4918 EXPECT_HR(hr, S_OK);
4919 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
4920 IXMLDOMNode_Release(node);
4921
4922 IXMLDOMNodeList_Release(list);
4923 }
4924
4925 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
4926 expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
4927
4928 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
4929 expect_list_and_release(list, "E3.E2.E2.D1");
4930
4931 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
4932 /* using get_item for query results advances the position */
4933 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
4934 expect_node(node, "E2.E2.D1");
4935 IXMLDOMNode_Release(node);
4936 ole_check(IXMLDOMNodeList_nextNode(list, &node));
4937 expect_node(node, "E4.E2.D1");
4938 IXMLDOMNode_Release(node);
4939 ole_check(IXMLDOMNodeList_reset(list));
4940 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
4941
4942 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
4943 expect_list_and_release(list, "E2.D1");
4944
4945 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
4946 ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
4947 ole_check(IXMLDOMNodeList_reset(list));
4948 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
4949
4950 /* select an attribute */
4951 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
4952 expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
4953
4954 /* would evaluate to a number */
4955 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
4956 /* would evaluate to a boolean */
4957 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
4958 /* would evaluate to a string */
4959 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
4960
4961 /* no results */
4962 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
4963 expect_list_and_release(list, "");
4964 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("elem//c"), &list));
4965 expect_list_and_release(list, "");
4966 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem[4]"), &list));
4967 expect_list_and_release(list, "");
4968 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
4969 expect_list_and_release(list, "");
4970
4971 /* foo undeclared in document node */
4972 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4973 /* undeclared in <root> node */
4974 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
4975 /* undeclared in <elem> node */
4976 ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
4977 /* but this trick can be used */
4978 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
4979 expect_list_and_release(list, "E3.E4.E2.D1");
4980
4981 /* it has to be declared in SelectionNamespaces */
4982 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4983 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
4984
4985 /* now the namespace can be used */
4986 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
4987 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4988 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
4989 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4990 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
4991 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4992 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
4993 expect_list_and_release(list, "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
4994
4995 /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
4996 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4997 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
4998
4999 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5000
5001 VariantInit(&var);
5002 ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
5003 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5004 if (V_VT(&var) == VT_BSTR)
5005 expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5006
5007 /* extra attributes - same thing*/
5008 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5009 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
5010 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
5011
5012 IXMLDOMNode_Release(rootNode);
5013 IXMLDOMNode_Release(elem1Node);
5014
5015 /* alter document with already built list */
5016 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5017 EXPECT_HR(hr, S_OK);
5018 EXPECT_LIST_LEN(list, 1);
5019
5020 hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5021 EXPECT_HR(hr, S_OK);
5022 EXPECT_REF(rootNode, 1);
5023 EXPECT_REF(doc, 1);
5024
5025 hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5026 EXPECT_HR(hr, S_OK);
5027 IXMLDOMNode_Release(rootNode);
5028
5029 EXPECT_LIST_LEN(list, 1);
5030
5031 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5032 EXPECT_HR(hr, S_OK);
5033 EXPECT_REF(rootNode, 1);
5034
5035 IXMLDOMNodeList_Release(list);
5036
5037 hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5038 EXPECT_HR(hr, S_OK);
5039 ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5040 SysFreeString(str);
5041 IXMLDOMNode_Release(rootNode);
5042
5043 /* alter node from list and get it another time */
5044 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5045 EXPECT_HR(hr, S_OK);
5046 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5047
5048 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5049 EXPECT_HR(hr, S_OK);
5050 EXPECT_LIST_LEN(list, 1);
5051
5052 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5053 EXPECT_HR(hr, S_OK);
5054
5055 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5056 EXPECT_HR(hr, S_OK);
5057
5058 V_VT(&var) = VT_I2;
5059 V_I2(&var) = 1;
5060 hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5061 EXPECT_HR(hr, S_OK);
5062 IXMLDOMElement_Release(elem);
5063 IXMLDOMNode_Release(rootNode);
5064
5065 /* now check attribute to be present */
5066 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5067 EXPECT_HR(hr, S_OK);
5068
5069 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5070 EXPECT_HR(hr, S_OK);
5071
5072 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5073 EXPECT_HR(hr, S_OK);
5074 IXMLDOMAttribute_Release(attr);
5075
5076 IXMLDOMElement_Release(elem);
5077 IXMLDOMNode_Release(rootNode);
5078
5079 /* and now check for attribute in original document */
5080 hr = IXMLDOMDocument2_get_documentElement(doc, &elem);
5081 EXPECT_HR(hr, S_OK);
5082
5083 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5084 EXPECT_HR(hr, S_OK);
5085 IXMLDOMAttribute_Release(attr);
5086
5087 IXMLDOMElement_Release(elem);
5088
5089 /* attach node from list to another document */
5090 doc2 = create_document(&IID_IXMLDOMDocument);
5091
5092 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5093 EXPECT_HR(hr, S_OK);
5094 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5095
5096 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5097 EXPECT_HR(hr, S_OK);
5098 EXPECT_LIST_LEN(list, 1);
5099
5100 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5101 EXPECT_HR(hr, S_OK);
5102 EXPECT_REF(rootNode, 1);
5103
5104 hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5105 EXPECT_HR(hr, S_OK);
5106 EXPECT_REF(rootNode, 1);
5107 EXPECT_REF(doc2, 1);
5108 EXPECT_REF(list, 1);
5109
5110 EXPECT_LIST_LEN(list, 1);
5111
5112 IXMLDOMNode_Release(rootNode);
5113 IXMLDOMNodeList_Release(list);
5114 IXMLDOMDocument_Release(doc2);
5115 IXMLDOMDocument2_Release(doc);
5116
5117 while (ptr->clsid)
5118 {
5119 if (is_clsid_supported(ptr->clsid, &IID_IXMLDOMDocument2))
5120 {
5121 hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5122 ok(hr == S_OK, "got 0x%08x\n", hr);
5123 }
5124 else
5125 {
5126 ptr++;
5127 continue;
5128 }
5129
5130 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5131 EXPECT_HR(hr, S_OK);
5132 ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5133
5134 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5135 EXPECT_HR(hr, S_OK);
5136
5137 V_VT(&var) = VT_BSTR;
5138 V_BSTR(&var) = _bstr_(ptr->ns);
5139
5140 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5141 ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5142
5143 V_VT(&var) = VT_EMPTY;
5144 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5145 EXPECT_HR(hr, S_OK);
5146 ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5147 ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5148 VariantClear(&var);
5149
5150 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5151 EXPECT_HR(hr, S_OK);
5152 if (hr == S_OK)
5153 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5154
5155 IXMLDOMDocument2_Release(doc);
5156 ptr++;
5157 free_bstrs();
5158 }
5159
5160 free_bstrs();
5161 }
5162
5163 static void test_cloneNode(void )
5164 {
5165 IXMLDOMDocument2 *doc, *doc_clone;
5166 IXMLDOMDocument *doc2;
5167 VARIANT_BOOL b;
5168 IXMLDOMNodeList *pList;
5169 IXMLDOMNamedNodeMap *mapAttr;
5170 LONG length, length1;
5171 LONG attr_cnt, attr_cnt1;
5172 IXMLDOMNode *node, *attr;
5173 IXMLDOMNode *node_clone;
5174 IXMLDOMNode *node_first;
5175 VARIANT v;
5176 HRESULT hr;
5177
5178 doc = create_document(&IID_IXMLDOMDocument2);
5179
5180 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b);
5181 ok(hr == S_OK, "got 0x%08x\n", hr);
5182 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5183
5184 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v);
5185 ok(hr == S_OK, "got 0x%08x\n", hr);
5186 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XSLPattern")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5187 VariantClear(&v);
5188
5189 V_BSTR(&v) = _bstr_("XPath");
5190 V_VT(&v) = VT_BSTR;
5191 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v);
5192 ok(hr == S_OK, "got 0x%08x\n", hr);
5193 VariantClear(&v);
5194
5195 /* clone document node */
5196 hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node);
5197 ok( hr == S_OK, "ret %08x\n", hr );
5198 ok( node != NULL, "node %p\n", node );
5199
5200 hr = IXMLDOMNode_get_childNodes(node, &pList);
5201 ok( hr == S_OK, "ret %08x\n", hr );
5202 length = 0;
5203 hr = IXMLDOMNodeList_get_length(pList, &length);
5204 ok( hr == S_OK, "ret %08x\n", hr );
5205 ok(length == 2, "got %d\n", length);
5206 IXMLDOMNodeList_Release(pList);
5207
5208 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone);
5209 ok(hr == S_OK, "got 0x%08x\n", hr);
5210
5211 /* cloned document inherits properties */
5212 hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v);
5213 ok(hr == S_OK, "got 0x%08x\n", hr);
5214 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XPath")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5215 VariantClear(&v);
5216
5217 IXMLDOMDocument2_Release(doc_clone);
5218 IXMLDOMNode_Release(node);
5219
5220 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5221 ok( hr == S_OK, "ret %08x\n", hr );
5222 ok( node != NULL, "node %p\n", node );
5223
5224 /* Check invalid parameter */
5225 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5226 ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5227
5228 /* All Children */
5229 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5230 ok( hr == S_OK, "ret %08x\n", hr );
5231 ok( node_clone != NULL, "node %p\n", node );
5232
5233 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5234 ok( hr == S_OK, "ret %08x\n", hr );
5235 hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5236 ok( hr == S_OK, "ret %08x\n", hr );
5237 IXMLDOMDocument_Release(doc2);
5238 IXMLDOMNode_Release(node_first);
5239
5240 hr = IXMLDOMNode_get_childNodes(node, &pList);
5241 ok( hr == S_OK, "ret %08x\n", hr );
5242 length = 0;
5243 hr = IXMLDOMNodeList_get_length(pList, &length);
5244 ok( hr == S_OK, "ret %08x\n", hr );
5245 ok(length == 1, "got %d\n", length);
5246 IXMLDOMNodeList_Release(pList);
5247
5248 hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5249 ok( hr == S_OK, "ret %08x\n", hr );
5250 attr_cnt = 0;
5251 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5252 ok( hr == S_OK, "ret %08x\n", hr );
5253 ok(attr_cnt == 3, "got %d\n", attr_cnt);
5254 IXMLDOMNamedNodeMap_Release(mapAttr);
5255
5256 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5257 ok( hr == S_OK, "ret %08x\n", hr );
5258 length1 = 0;
5259 hr = IXMLDOMNodeList_get_length(pList, &length1);
5260 ok(length1 == 1, "got %d\n", length1);
5261 ok( hr == S_OK, "ret %08x\n", hr );
5262 IXMLDOMNodeList_Release(pList);
5263
5264 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5265 ok( hr == S_OK, "ret %08x\n", hr );
5266 attr_cnt1 = 0;
5267 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5268 ok( hr == S_OK, "ret %08x\n", hr );
5269 ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5270 /* now really get some attributes from cloned element */
5271 attr = NULL;
5272 hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr);
5273 ok(hr == S_OK, "ret %08x\n", hr);
5274 IXMLDOMNode_Release(attr);
5275 IXMLDOMNamedNodeMap_Release(mapAttr);
5276
5277 ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5278 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5279 IXMLDOMNode_Release(node_clone);
5280
5281 /* No Children */
5282 hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5283 ok( hr == S_OK, "ret %08x\n", hr );
5284 ok( node_clone != NULL, "node %p\n", node );
5285
5286 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5287 ok(hr == S_FALSE, "ret %08x\n", hr );
5288
5289 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5290 ok(hr == S_OK, "ret %08x\n", hr );
5291 hr = IXMLDOMNodeList_get_length(pList, &length1);
5292 ok(hr == S_OK, "ret %08x\n", hr );
5293 ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5294 IXMLDOMNodeList_Release(pList);
5295
5296 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5297 ok(hr == S_OK, "ret %08x\n", hr );
5298 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5299 ok(hr == S_OK, "ret %08x\n", hr );
5300 ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5301 IXMLDOMNamedNodeMap_Release(mapAttr);
5302
5303 ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5304 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5305 IXMLDOMNode_Release(node_clone);
5306
5307 IXMLDOMNode_Release(node);
5308 IXMLDOMDocument2_Release(doc);
5309 free_bstrs();
5310 }
5311
5312 static void test_xmlTypes(void)
5313 {
5314 IXMLDOMDocument *doc;
5315 IXMLDOMElement *pRoot;
5316 HRESULT hr;
5317 IXMLDOMComment *pComment;
5318 IXMLDOMElement *pElement;
5319 IXMLDOMAttribute *pAttribute;
5320 IXMLDOMNamedNodeMap *pAttribs;
5321 IXMLDOMCDATASection *pCDataSec;
5322 IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5323 IXMLDOMDocumentFragment *pDocFrag = NULL;
5324 IXMLDOMEntityReference *pEntityRef = NULL;
5325 BSTR str;
5326 IXMLDOMNode *pNextChild;
5327 VARIANT v;
5328 LONG len = 0;
5329
5330 doc = create_document(&IID_IXMLDOMDocument);
5331
5332 hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5333 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5334
5335 pNextChild = (void*)0xdeadbeef;
5336 hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5337 ok(hr == S_FALSE, "ret %08x\n", hr );
5338 ok(pNextChild == NULL, "pDocChild not NULL\n");
5339
5340 /* test previous Sibling */
5341 hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5342 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5343
5344 pNextChild = (void*)0xdeadbeef;
5345 hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5346 ok(hr == S_FALSE, "ret %08x\n", hr );
5347 ok(pNextChild == NULL, "pNextChild not NULL\n");
5348
5349 /* test get_dataType */
5350 V_VT(&v) = VT_EMPTY;
5351 hr = IXMLDOMDocument_get_dataType(doc, &v);
5352 ok(hr == S_FALSE, "ret %08x\n", hr );
5353 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5354 VariantClear(&v);
5355
5356 /* test implementation */
5357 hr = IXMLDOMDocument_get_implementation(doc, NULL);
5358 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5359
5360 hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5361 ok(hr == S_OK, "ret %08x\n", hr );
5362 if(hr == S_OK)
5363 {
5364 VARIANT_BOOL hasFeature = VARIANT_TRUE;
5365 BSTR sEmpty = SysAllocStringLen(NULL, 0);
5366
5367 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5368 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5369
5370 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5371 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5372
5373 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5374 ok(hr == S_OK, "ret %08x\n", hr );
5375 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5376
5377 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5378 ok(hr == S_OK, "ret %08x\n", hr );
5379 ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5380
5381 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5382 ok(hr == S_OK, "ret %08x\n", hr );
5383 ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5384
5385 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5386 ok(hr == S_OK, "ret %08x\n", hr );
5387 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5388
5389 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5390 ok(hr == S_OK, "ret %08x\n", hr );
5391 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5392
5393 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5394 ok(hr == S_OK, "ret %08x\n", hr );
5395 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5396
5397 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5398 ok(hr == S_OK, "ret %08x\n", hr );
5399 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5400
5401 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5402 ok(hr == S_OK, "ret %08x\n", hr );
5403 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5404
5405 SysFreeString(sEmpty);
5406 IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5407 }
5408
5409 pRoot = (IXMLDOMElement*)0x1;
5410 hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5411 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5412 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5413
5414 pRoot = (IXMLDOMElement*)0x1;
5415 hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5416 ok(hr == E_FAIL, "ret %08x\n", hr );
5417 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5418
5419 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5420 ok(hr == S_OK, "ret %08x\n", hr );
5421 if(hr == S_OK)
5422 {
5423 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5424 ok(hr == S_OK, "ret %08x\n", hr );
5425 if(hr == S_OK)
5426 {
5427 /* Comment */
5428 str = SysAllocString(szComment);
5429 hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5430 SysFreeString(str);
5431 ok(hr == S_OK, "ret %08x\n", hr );
5432 if(hr == S_OK)
5433 {
5434 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5435 ok(hr == S_OK, "ret %08x\n", hr );
5436
5437 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5438 ok(hr == S_OK, "ret %08x\n", hr );
5439 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
5440 SysFreeString(str);
5441
5442 hr = IXMLDOMComment_get_xml(pComment, &str);
5443 ok(hr == S_OK, "ret %08x\n", hr );
5444 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
5445 SysFreeString(str);
5446
5447 /* put data Tests */
5448 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5449 ok(hr == S_OK, "ret %08x\n", hr );
5450
5451 /* get data Tests */
5452 hr = IXMLDOMComment_get_data(pComment, &str);
5453 ok(hr == S_OK, "ret %08x\n", hr );
5454 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
5455 SysFreeString(str);
5456
5457 /* Confirm XML text is good */
5458 hr = IXMLDOMComment_get_xml(pComment, &str);
5459 ok(hr == S_OK, "ret %08x\n", hr );
5460 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
5461 SysFreeString(str);
5462
5463 /* Confirm we get the put_data Text back */
5464 hr = IXMLDOMComment_get_text(pComment, &str);
5465 ok(hr == S_OK, "ret %08x\n", hr );
5466 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
5467 SysFreeString(str);
5468
5469 /* test length property */
5470 hr = IXMLDOMComment_get_length(pComment, &len);
5471 ok(hr == S_OK, "ret %08x\n", hr );
5472 ok(len == 21, "expected 21 got %d\n", len);
5473
5474 /* test substringData */
5475 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5476 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5477
5478 /* test substringData - Invalid offset */
5479 str = (void *)0xdeadbeef;
5480 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5481 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5482 ok( str == NULL, "incorrect string\n");
5483
5484 /* test substringData - Invalid offset */
5485 str = (void *)0xdeadbeef;
5486 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5487 ok(hr == S_FALSE, "ret %08x\n", hr );
5488 ok( str == NULL, "incorrect string\n");
5489
5490 /* test substringData - Invalid size */
5491 str = (void *)0xdeadbeef;
5492 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5493 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5494 ok( str == NULL, "incorrect string\n");
5495
5496 /* test substringData - Invalid size */
5497 str = (void *)0xdeadbeef;
5498 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5499 ok(hr == S_FALSE, "ret %08x\n", hr );
5500 ok( str == NULL, "incorrect string\n");
5501
5502 /* test substringData - Start of string */
5503 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5504 ok(hr == S_OK, "ret %08x\n", hr );
5505 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5506 SysFreeString(str);
5507
5508 /* test substringData - Middle of string */
5509 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5510 ok(hr == S_OK, "ret %08x\n", hr );
5511 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5512 SysFreeString(str);
5513
5514 /* test substringData - End of string */
5515 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5516 ok(hr == S_OK, "ret %08x\n", hr );
5517 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5518 SysFreeString(str);
5519
5520 /* test appendData */
5521 hr = IXMLDOMComment_appendData(pComment, NULL);
5522 ok(hr == S_OK, "ret %08x\n", hr );
5523
5524 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5525 ok(hr == S_OK, "ret %08x\n", hr );
5526
5527 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5528 ok(hr == S_OK, "ret %08x\n", hr );
5529
5530 hr = IXMLDOMComment_get_text(pComment, &str);
5531 ok(hr == S_OK, "ret %08x\n", hr );
5532 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5533 SysFreeString(str);
5534
5535 /* test insertData */
5536 str = SysAllocStringLen(NULL, 0);
5537 hr = IXMLDOMComment_insertData(pComment, -1, str);
5538 ok(hr == S_OK, "ret %08x\n", hr );
5539
5540 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5541 ok(hr == S_OK, "ret %08x\n", hr );
5542
5543 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5544 ok(hr == S_OK, "ret %08x\n", hr );
5545
5546 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5547 ok(hr == S_OK, "ret %08x\n", hr );
5548
5549 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5550 ok(hr == S_OK, "ret %08x\n", hr );
5551
5552 hr = IXMLDOMComment_insertData(pComment, 0, str);
5553 ok(hr == S_OK, "ret %08x\n", hr );
5554 SysFreeString(str);
5555
5556 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5557 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5558
5559 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5560 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5561
5562 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5563 ok(hr == S_OK, "ret %08x\n", hr );
5564
5565 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5566 ok(hr == S_OK, "ret %08x\n", hr );
5567
5568 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5569 ok(hr == S_OK, "ret %08x\n", hr );
5570
5571 hr = IXMLDOMComment_get_text(pComment, &str);
5572 ok(hr == S_OK, "ret %08x\n", hr );
5573 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5574 SysFreeString(str);
5575
5576 /* delete data */
5577 /* invalid arguments */
5578 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
5579 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5580
5581 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
5582 ok(hr == S_OK, "ret %08x\n", hr );
5583
5584 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
5585 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5586
5587 hr = IXMLDOMComment_get_length(pComment, &len);
5588 ok(hr == S_OK, "ret %08x\n", hr );
5589 ok(len == 43, "expected 43 got %d\n", len);
5590
5591 hr = IXMLDOMComment_deleteData(pComment, len, 1);
5592 ok(hr == S_OK, "ret %08x\n", hr );
5593
5594 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
5595 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5596
5597 /* delete from start */
5598 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
5599 ok(hr == S_OK, "ret %08x\n", hr );
5600
5601 hr = IXMLDOMComment_get_length(pComment, &len);
5602 ok(hr == S_OK, "ret %08x\n", hr );
5603 ok(len == 38, "expected 38 got %d\n", len);
5604
5605 hr = IXMLDOMComment_get_text(pComment, &str);
5606 ok(hr == S_OK, "ret %08x\n", hr );
5607 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5608 SysFreeString(str);
5609
5610 /* delete from end */
5611 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
5612 ok(hr == S_OK, "ret %08x\n", hr );
5613
5614 hr = IXMLDOMComment_get_length(pComment, &len);
5615 ok(hr == S_OK, "ret %08x\n", hr );
5616 ok(len == 35, "expected 35 got %d\n", len);
5617
5618 hr = IXMLDOMComment_get_text(pComment, &str);
5619 ok(hr == S_OK, "ret %08x\n", hr );
5620 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5621 SysFreeString(str);
5622
5623 /* delete from inside */
5624 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
5625 ok(hr == S_OK, "ret %08x\n", hr );
5626
5627 hr = IXMLDOMComment_get_length(pComment, &len);
5628 ok(hr == S_OK, "ret %08x\n", hr );
5629 ok(len == 2, "expected 2 got %d\n", len);
5630
5631 hr = IXMLDOMComment_get_text(pComment, &str);
5632 ok(hr == S_OK, "ret %08x\n", hr );
5633 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5634 SysFreeString(str);
5635
5636 /* delete whole data ... */
5637 hr = IXMLDOMComment_get_length(pComment, &len);
5638 ok(hr == S_OK, "ret %08x\n", hr );
5639
5640 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5641 ok(hr == S_OK, "ret %08x\n", hr );
5642 /* ... and try again with empty string */
5643 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5644 ok(hr == S_OK, "ret %08x\n", hr );
5645
5646 /* ::replaceData() */
5647 V_VT(&v) = VT_BSTR;
5648 V_BSTR(&v) = SysAllocString(szstr1);
5649 hr = IXMLDOMComment_put_nodeValue(pComment, v);
5650 ok(hr == S_OK, "ret %08x\n", hr );
5651 VariantClear(&v);
5652
5653 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
5654 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5655 hr = IXMLDOMComment_get_text(pComment, &str);
5656 ok(hr == S_OK, "ret %08x\n", hr );
5657 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5658 SysFreeString(str);
5659
5660 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
5661 ok(hr == S_OK, "ret %08x\n", hr );
5662 hr = IXMLDOMComment_get_text(pComment, &str);
5663 ok(hr == S_OK, "ret %08x\n", hr );
5664 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5665 SysFreeString(str);
5666
5667 /* NULL pointer means delete */
5668 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
5669 ok(hr == S_OK, "ret %08x\n", hr );
5670 hr = IXMLDOMComment_get_text(pComment, &str);
5671 ok(hr == S_OK, "ret %08x\n", hr );
5672 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5673 SysFreeString(str);
5674
5675 /* empty string means delete */
5676 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
5677 ok(hr == S_OK, "ret %08x\n", hr );
5678 hr = IXMLDOMComment_get_text(pComment, &str);
5679 ok(hr == S_OK, "ret %08x\n", hr );
5680 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5681 SysFreeString(str);
5682
5683 /* zero count means insert */
5684 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
5685 ok(hr == S_OK, "ret %08x\n", hr );
5686 hr = IXMLDOMComment_get_text(pComment, &str);
5687 ok(hr == S_OK, "ret %08x\n", hr );
5688 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5689 SysFreeString(str);
5690
5691 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
5692 ok(hr == S_OK, "ret %08x\n", hr );
5693
5694 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
5695 ok(hr == S_OK, "ret %08x\n", hr );
5696 hr = IXMLDOMComment_get_text(pComment, &str);
5697 ok(hr == S_OK, "ret %08x\n", hr );
5698 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5699 SysFreeString(str);
5700
5701 /* nonempty string, count greater than its length */
5702 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
5703 ok(hr == S_OK, "ret %08x\n", hr );
5704 hr = IXMLDOMComment_get_text(pComment, &str);
5705 ok(hr == S_OK, "ret %08x\n", hr );
5706 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5707 SysFreeString(str);
5708
5709 /* nonempty string, count less than its length */
5710 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
5711 ok(hr == S_OK, "ret %08x\n", hr );
5712 hr = IXMLDOMComment_get_text(pComment, &str);
5713 ok(hr == S_OK, "ret %08x\n", hr );
5714 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5715 SysFreeString(str);
5716
5717 IXMLDOMComment_Release(pComment);
5718 }
5719
5720 /* Element */
5721 str = SysAllocString(szElement);
5722 hr = IXMLDOMDocument_createElement(doc, str, &pElement);
5723 SysFreeString(str);
5724 ok(hr == S_OK, "ret %08x\n", hr );
5725 if(hr == S_OK)
5726 {
5727 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5728 ok(hr == S_OK, "ret %08x\n", hr );
5729
5730 hr = IXMLDOMElement_get_nodeName(pElement, &str);
5731 ok(hr == S_OK, "ret %08x\n", hr );
5732 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
5733 SysFreeString(str);
5734
5735 hr = IXMLDOMElement_get_xml(pElement, &str);
5736 ok(hr == S_OK, "ret %08x\n", hr );
5737 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
5738 SysFreeString(str);
5739
5740 /* Attribute */
5741 pAttribute = (IXMLDOMAttribute*)0x1;
5742 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
5743 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5744 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5745
5746 pAttribute = (IXMLDOMAttribute*)0x1;
5747 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
5748 ok(hr == E_FAIL, "ret %08x\n", hr );
5749 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5750
5751 str = SysAllocString(szAttribute);
5752 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
5753 SysFreeString(str);
5754 ok(hr == S_OK, "ret %08x\n", hr );
5755 if(hr == S_OK)
5756 {
5757 IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
5758
5759 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
5760 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5761
5762 pNextChild = (IXMLDOMNode *)0x1;
5763 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
5764 ok(hr == S_FALSE, "ret %08x\n", hr );
5765 ok(pNextChild == NULL, "pNextChild not NULL\n");
5766
5767 /* test Previous Sibling*/
5768 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
5769 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5770
5771 pNextChild = (IXMLDOMNode *)0x1;
5772 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
5773 ok(hr == S_FALSE, "ret %08x\n", hr );
5774 ok(pNextChild == NULL, "pNextChild not NULL\n");
5775
5776 hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
5777 ok(hr == E_FAIL, "ret %08x\n", hr );
5778 ok(pNewChild == NULL, "pNewChild not NULL\n");
5779
5780 hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
5781 ok(hr == S_OK, "ret %08x\n", hr );
5782 if ( hr == S_OK )
5783 {
5784 hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
5785 ok(hr == S_OK, "ret %08x\n", hr );
5786
5787 IXMLDOMNamedNodeMap_Release(pAttribs);
5788 }
5789
5790 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5791 ok(hr == S_OK, "ret %08x\n", hr );
5792 ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
5793 SysFreeString(str);
5794
5795 /* test nodeName */
5796 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5797 ok(hr == S_OK, "ret %08x\n", hr );
5798 ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
5799 SysFreeString(str);
5800
5801 /* test name property */
5802 hr = IXMLDOMAttribute_get_name(pAttribute, &str);
5803 ok(hr == S_OK, "ret %08x\n", hr );
5804 ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
5805 SysFreeString(str);
5806
5807 hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
5808 ok(hr == S_OK, "ret %08x\n", hr );
5809 ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
5810 SysFreeString(str);
5811
5812 IXMLDOMAttribute_Release(pAttribute);
5813
5814 /* Check Element again with the Add Attribute*/
5815 hr = IXMLDOMElement_get_xml(pElement, &str);
5816 ok(hr == S_OK, "ret %08x\n", hr );
5817 ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
5818 SysFreeString(str);
5819 }
5820
5821 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
5822 ok(hr == S_OK, "ret %08x\n", hr );
5823
5824 hr = IXMLDOMElement_get_xml(pElement, &str);
5825 ok(hr == S_OK, "ret %08x\n", hr );
5826 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
5827 SysFreeString(str);
5828
5829 /* Test for reversible escaping */
5830 str = SysAllocString( szStrangeChars );
5831 hr = IXMLDOMElement_put_text(pElement, str);
5832 ok(hr == S_OK, "ret %08x\n", hr );
5833 SysFreeString( str );
5834
5835 hr = IXMLDOMElement_get_xml(pElement, &str);
5836 ok(hr == S_OK, "ret %08x\n", hr );
5837 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
5838 SysFreeString(str);
5839
5840 hr = IXMLDOMElement_get_text(pElement, &str);
5841 ok(hr == S_OK, "ret %08x\n", hr );
5842 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
5843 SysFreeString(str);
5844
5845 IXMLDOMElement_Release(pElement);
5846 }
5847
5848 /* CData Section */
5849 str = SysAllocString(szCData);
5850 hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
5851 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5852
5853 hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
5854 SysFreeString(str);
5855 ok(hr == S_OK, "ret %08x\n", hr );
5856 if(hr == S_OK)
5857 {
5858 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
5859 VARIANT var;
5860
5861 VariantInit(&var);
5862
5863 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
5864 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
5865
5866 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
5867 ok(hr == S_OK, "ret %08x\n", hr );
5868
5869 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
5870 ok(hr == S_OK, "ret %08x\n", hr );
5871 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
5872 SysFreeString(str);
5873
5874 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
5875 ok(hr == S_OK, "ret %08x\n", hr );
5876 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
5877 SysFreeString(str);
5878
5879 /* test lastChild */
5880 pNextChild = (IXMLDOMNode*)0x1;
5881 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
5882 ok(hr == S_FALSE, "ret %08x\n", hr );
5883 ok(pNextChild == NULL, "pNextChild not NULL\n");
5884
5885 /* put data Tests */
5886 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
5887 ok(hr == S_OK, "ret %08x\n", hr );
5888
5889 /* Confirm XML text is good */
5890 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
5891 ok(hr == S_OK, "ret %08x\n", hr );
5892 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
5893 SysFreeString(str);
5894
5895 /* Confirm we get the put_data Text back */
5896 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5897 ok(hr == S_OK, "ret %08x\n", hr );
5898 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
5899 SysFreeString(str);
5900
5901 /* test length property */
5902 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5903 ok(hr == S_OK, "ret %08x\n", hr );
5904 ok(len == 21, "expected 21 got %d\n", len);
5905
5906 /* test get data */
5907 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
5908 ok(hr == S_OK, "ret %08x\n", hr );
5909 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
5910 SysFreeString(str);
5911
5912 /* test substringData */
5913 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
5914 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5915
5916 /* test substringData - Invalid offset */
5917 str = (void *)0xdeadbeef;
5918 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
5919 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5920 ok( str == NULL, "incorrect string\n");
5921
5922 /* test substringData - Invalid offset */
5923 str = (void *)0xdeadbeef;
5924 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
5925 ok(hr == S_FALSE, "ret %08x\n", hr );
5926 ok( str == NULL, "incorrect string\n");
5927
5928 /* test substringData - Invalid size */
5929 str = (void *)0xdeadbeef;
5930 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
5931 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5932 ok( str == NULL, "incorrect string\n");
5933
5934 /* test substringData - Invalid size */
5935 str = (void *)0xdeadbeef;
5936 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
5937 ok(hr == S_FALSE, "ret %08x\n", hr );
5938 ok( str == NULL, "incorrect string\n");
5939
5940 /* test substringData - Start of string */
5941 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
5942 ok(hr == S_OK, "ret %08x\n", hr );
5943 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5944 SysFreeString(str);
5945
5946 /* test substringData - Middle of string */
5947 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
5948 ok(hr == S_OK, "ret %08x\n", hr );
5949 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5950 SysFreeString(str);
5951
5952 /* test substringData - End of string */
5953 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
5954 ok(hr == S_OK, "ret %08x\n", hr );
5955 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5956 SysFreeString(str);
5957
5958 /* test appendData */
5959 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
5960 ok(hr == S_OK, "ret %08x\n", hr );
5961
5962 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
5963 ok(hr == S_OK, "ret %08x\n", hr );
5964
5965 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
5966 ok(hr == S_OK, "ret %08x\n", hr );
5967
5968 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5969 ok(hr == S_OK, "ret %08x\n", hr );
5970 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5971 SysFreeString(str);
5972
5973 /* test insertData */
5974 str = SysAllocStringLen(NULL, 0);
5975 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
5976 ok(hr == S_OK, "ret %08x\n", hr );
5977
5978 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
5979 ok(hr == S_OK, "ret %08x\n", hr );
5980
5981 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
5982 ok(hr == S_OK, "ret %08x\n", hr );
5983
5984 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
5985 ok(hr == S_OK, "ret %08x\n", hr );
5986
5987 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
5988 ok(hr == S_OK, "ret %08x\n", hr );
5989
5990 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
5991 ok(hr == S_OK, "ret %08x\n", hr );
5992 SysFreeString(str);
5993
5994 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
5995 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5996
5997 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
5998 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5999
6000 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6001 ok(hr == S_OK, "ret %08x\n", hr );
6002
6003 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6004 ok(hr == S_OK, "ret %08x\n", hr );
6005
6006 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6007 ok(hr == S_OK, "ret %08x\n", hr );
6008
6009 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6010 ok(hr == S_OK, "ret %08x\n", hr );
6011 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6012 SysFreeString(str);
6013
6014 /* delete data */
6015 /* invalid arguments */
6016 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6017 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6018
6019 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6020 ok(hr == S_OK, "ret %08x\n", hr );
6021
6022 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6023 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6024
6025 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6026 ok(hr == S_OK, "ret %08x\n", hr );
6027 ok(len == 43, "expected 43 got %d\n", len);
6028
6029 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6030 ok(hr == S_OK, "ret %08x\n", hr );
6031
6032 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6033 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6034
6035 /* delete from start */
6036 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6037 ok(hr == S_OK, "ret %08x\n", hr );
6038
6039 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6040 ok(hr == S_OK, "ret %08x\n", hr );
6041 ok(len == 38, "expected 38 got %d\n", len);
6042
6043 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6044 ok(hr == S_OK, "ret %08x\n", hr );
6045 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6046 SysFreeString(str);
6047
6048 /* delete from end */
6049 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6050 ok(hr == S_OK, "ret %08x\n", hr );
6051
6052 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6053 ok(hr == S_OK, "ret %08x\n", hr );
6054 ok(len == 35, "expected 35 got %d\n", len);
6055
6056 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6057 ok(hr == S_OK, "ret %08x\n", hr );
6058 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6059 SysFreeString(str);
6060
6061 /* delete from inside */
6062 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6063 ok(hr == S_OK, "ret %08x\n", hr );
6064
6065 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6066 ok(hr == S_OK, "ret %08x\n", hr );
6067 ok(len == 2, "expected 2 got %d\n", len);
6068
6069 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6070 ok(hr == S_OK, "ret %08x\n", hr );
6071 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6072 SysFreeString(str);
6073
6074 /* delete whole data ... */
6075 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6076 ok(hr == S_OK, "ret %08x\n", hr );
6077
6078 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6079 ok(hr == S_OK, "ret %08x\n", hr );
6080
6081 /* ... and try again with empty string */
6082 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6083 ok(hr == S_OK, "ret %08x\n", hr );
6084
6085 /* ::replaceData() */
6086 V_VT(&v) = VT_BSTR;
6087 V_BSTR(&v) = SysAllocString(szstr1);
6088 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6089 ok(hr == S_OK, "ret %08x\n", hr );
6090 VariantClear(&v);
6091
6092 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6093 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6094 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6095 ok(hr == S_OK, "ret %08x\n", hr );
6096 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6097 SysFreeString(str);
6098
6099 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6100 ok(hr == S_OK, "ret %08x\n", hr );
6101 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6102 ok(hr == S_OK, "ret %08x\n", hr );
6103 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6104 SysFreeString(str);
6105
6106 /* NULL pointer means delete */
6107 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6108 ok(hr == S_OK, "ret %08x\n", hr );
6109 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6110 ok(hr == S_OK, "ret %08x\n", hr );
6111 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6112 SysFreeString(str);
6113
6114 /* empty string means delete */
6115 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6116 ok(hr == S_OK, "ret %08x\n", hr );
6117 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6118 ok(hr == S_OK, "ret %08x\n", hr );
6119 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6120 SysFreeString(str);
6121
6122 /* zero count means insert */
6123 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6124 ok(hr == S_OK, "ret %08x\n", hr );
6125 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6126 ok(hr == S_OK, "ret %08x\n", hr );
6127 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6128 SysFreeString(str);
6129
6130 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6131 ok(hr == S_OK, "ret %08x\n", hr );
6132
6133 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6134 ok(hr == S_OK, "ret %08x\n", hr );
6135 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6136 ok(hr == S_OK, "ret %08x\n", hr );
6137 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6138 SysFreeString(str);
6139
6140 /* nonempty string, count greater than its length */
6141 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6142 ok(hr == S_OK, "ret %08x\n", hr );
6143 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6144 ok(hr == S_OK, "ret %08x\n", hr );
6145 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6146 SysFreeString(str);
6147
6148 /* nonempty string, count less than its length */
6149 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6150 ok(hr == S_OK, "ret %08x\n", hr );
6151 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6152 ok(hr == S_OK, "ret %08x\n", hr );
6153 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6154 SysFreeString(str);
6155
6156 IXMLDOMCDATASection_Release(pCDataSec);
6157 }
6158
6159 /* Document Fragments */
6160 hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6161 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6162
6163 hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6164 ok(hr == S_OK, "ret %08x\n", hr );
6165 if(hr == S_OK)
6166 {
6167 IXMLDOMNode *node;
6168
6169 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6170 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6171
6172 node = (IXMLDOMNode *)0x1;
6173 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6174 ok(hr == S_FALSE, "ret %08x\n", hr );
6175 ok(node == NULL, "expected NULL, got %p\n", node);
6176
6177 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6178 ok(hr == S_OK, "ret %08x\n", hr );
6179
6180 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6181 ok(hr == S_OK, "ret %08x\n", hr );
6182 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6183 SysFreeString(str);
6184
6185 /* test next Sibling*/
6186 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6187 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6188
6189 node = (IXMLDOMNode *)0x1;
6190 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6191 ok(hr == S_FALSE, "ret %08x\n", hr );
6192 ok(node == NULL, "next sibling not NULL\n");
6193
6194 /* test Previous Sibling*/
6195 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6196 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6197
6198 node = (IXMLDOMNode *)0x1;
6199 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6200 ok(hr == S_FALSE, "ret %08x\n", hr );
6201 ok(node == NULL, "previous sibling not NULL\n");
6202
6203 IXMLDOMDocumentFragment_Release(pDocFrag);
6204 }
6205
6206 /* Entity References */
6207 hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6208 ok(hr == E_FAIL, "ret %08x\n", hr );
6209 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6210 ok(hr == E_FAIL, "ret %08x\n", hr );
6211
6212 str = SysAllocString(szEntityRef);
6213 hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6214 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6215
6216 hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6217 SysFreeString(str);
6218 ok(hr == S_OK, "ret %08x\n", hr );
6219 if(hr == S_OK)
6220 {
6221 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6222 ok(hr == S_OK, "ret %08x\n", hr );
6223
6224 /* test get_xml*/
6225 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6226 ok(hr == S_OK, "ret %08x\n", hr );
6227 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6228 SysFreeString(str);
6229
6230 IXMLDOMEntityReference_Release(pEntityRef);
6231 }
6232
6233 IXMLDOMElement_Release( pRoot );
6234 }
6235 }
6236
6237 IXMLDOMDocument_Release(doc);
6238
6239 free_bstrs();
6240 }
6241
6242 typedef struct {
6243 const char *name;
6244 const char *type;
6245 HRESULT hr;
6246 } put_datatype_t;
6247
6248 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6249 So many of the names have been changed to reflect this. */
6250 static put_datatype_t put_datatype_data[] = {
6251 { "test_inval", "abcdefg", E_FAIL },
6252 { "test_bool", "Boolean", S_OK },
6253 { "test_string", "String", S_OK },
6254 { "test_number", "number", S_OK },
6255 { "test_int", "InT", S_OK },
6256 { "test_fixed", "fixed.14.4", S_OK },
6257 { "test_datetime", "DateTime", S_OK },
6258 { "test_datetimetz", "DateTime.tz", S_OK },
6259 { "test_date", "Date", S_OK },
6260 { "test_time", "Time", S_OK },
6261 { "test_timetz", "Time.tz", S_OK },
6262 { "test_I1", "I1", S_OK },
6263 { "test_I2", "I2", S_OK },
6264 { "test_I4", "I4", S_OK },
6265 { "test_UI1", "UI1", S_OK },
6266 { "test_UI2", "UI2", S_OK },
6267 { "test_UI4", "UI4", S_OK },
6268 { "test_r4", "r4", S_OK },
6269 { "test_r8", "r8", S_OK },
6270 { "test_float", "float", S_OK },
6271 { "test_uuid", "UuId", S_OK },
6272 { "test_binhex", "bin.hex", S_OK },
6273 { "test_binbase64", "bin.base64", S_OK },
6274 { NULL }
6275 };
6276
6277 typedef struct {
6278 DOMNodeType type;
6279 HRESULT hr;
6280 } put_datatype_notype_t;
6281
6282 static put_datatype_notype_t put_dt_notype[] = {
6283 { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6284 { NODE_DOCUMENT_FRAGMENT, E_FAIL },
6285 { NODE_ENTITY_REFERENCE, E_FAIL },
6286 { NODE_CDATA_SECTION, E_FAIL },
6287 { NODE_COMMENT, E_FAIL },
6288 { NODE_INVALID }
6289 };
6290
6291 static void test_put_dataType( void )
6292 {
6293 const put_datatype_notype_t *ptr2 = put_dt_notype;
6294 const put_datatype_t *ptr = put_datatype_data;
6295 IXMLDOMElement *root, *element;
6296 BSTR nameW, type1W, type2W;
6297 IXMLDOMDocument *doc;
6298 HRESULT hr;
6299
6300 doc = create_document(&IID_IXMLDOMDocument);
6301
6302 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6303 EXPECT_HR(hr, E_INVALIDARG);
6304
6305 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6306 EXPECT_HR(hr, S_OK);
6307
6308 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6309 EXPECT_HR(hr, S_OK);
6310
6311 hr = IXMLDOMElement_put_dataType(root, NULL);
6312 EXPECT_HR(hr, E_INVALIDARG);
6313
6314 while (ptr->name)
6315 {
6316 hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6317 EXPECT_HR(hr, S_OK);
6318 if(hr == S_OK)
6319 {
6320 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6321 EXPECT_HR(hr, S_OK);
6322
6323 hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6324 ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6325
6326 IXMLDOMElement_Release(element);
6327 }
6328 ptr++;
6329 }
6330
6331 /* check changing types */
6332 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6333 EXPECT_HR(hr, S_OK);
6334
6335 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6336 EXPECT_HR(hr, S_OK);
6337
6338 hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6339 EXPECT_HR(hr, S_OK);
6340
6341 hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6342 EXPECT_HR(hr, S_OK);
6343
6344 IXMLDOMElement_Release(element);
6345
6346 /* try to set type for node without a type */
6347 nameW = _bstr_("testname");
6348 type1W = _bstr_("string");
6349 type2W = _bstr_("number");
6350 while (ptr2->type != NODE_INVALID)
6351 {
6352 IXMLDOMNode *node;
6353 VARIANT type;
6354
6355 V_VT(&type) = VT_I2;
6356 V_I2(&type) = ptr2->type;
6357
6358 hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
6359 EXPECT_HR(hr, S_OK);
6360 if(hr == S_OK)
6361 {
6362 hr = IXMLDOMElement_appendChild(root, node, NULL);
6363 EXPECT_HR(hr, S_OK);
6364
6365 hr = IXMLDOMNode_put_dataType(node, NULL);
6366 EXPECT_HR(hr, E_INVALIDARG);
6367
6368 hr = IXMLDOMNode_put_dataType(node, type1W);
6369 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6370 hr = IXMLDOMNode_put_dataType(node, type2W);
6371 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6372
6373 IXMLDOMNode_Release(node);
6374 }
6375 ptr2++;
6376 }
6377
6378 IXMLDOMElement_Release(root);
6379 IXMLDOMDocument_Release(doc);
6380 free_bstrs();
6381 }
6382
6383 static void test_save(void)
6384 {
6385 IXMLDOMDocument *doc, *doc2;
6386 IXMLDOMElement *root;
6387 BSTR sOrig, sNew, filename;
6388 char buffer[100];
6389 IStream *stream;
6390 HGLOBAL global;
6391 VARIANT_BOOL b;
6392 DWORD read = 0;
6393 VARIANT dest;
6394 HANDLE hfile;
6395 HRESULT hr;
6396 char *ptr;
6397
6398 doc = create_document(&IID_IXMLDOMDocument);
6399 doc2 = create_document(&IID_IXMLDOMDocument);
6400
6401 /* save to IXMLDOMDocument */
6402 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6403 EXPECT_HR(hr, S_OK);
6404
6405 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6406 EXPECT_HR(hr, S_OK);
6407
6408 V_VT(&dest) = VT_UNKNOWN;
6409 V_UNKNOWN(&dest) = (IUnknown*)doc2;
6410
6411 hr = IXMLDOMDocument_save(doc, dest);
6412 EXPECT_HR(hr, S_OK);
6413
6414 hr = IXMLDOMDocument_get_xml(doc, &sOrig);
6415 EXPECT_HR(hr, S_OK);
6416
6417 hr = IXMLDOMDocument_get_xml(doc2, &sNew);
6418 EXPECT_HR(hr, S_OK);
6419
6420 ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
6421
6422 SysFreeString(sOrig);
6423 SysFreeString(sNew);
6424
6425 IXMLDOMElement_Release(root);
6426 IXMLDOMDocument_Release(doc2);
6427
6428 /* save to path */
6429 V_VT(&dest) = VT_BSTR;
6430 V_BSTR(&dest) = _bstr_("test.xml");
6431
6432 hr = IXMLDOMDocument_save(doc, dest);
6433 EXPECT_HR(hr, S_OK);
6434
6435 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6436 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6437 if(hfile == INVALID_HANDLE_VALUE) return;
6438
6439 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6440 ok(read != 0, "could not read file\n");
6441 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6442
6443 CloseHandle(hfile);
6444 DeleteFileA("test.xml");
6445
6446 /* save to path VT_BSTR | VT_BYREF */
6447 filename = _bstr_("test.xml");
6448 V_VT(&dest) = VT_BSTR | VT_BYREF;
6449 V_BSTRREF(&dest) = &filename;
6450
6451 hr = IXMLDOMDocument_save(doc, dest);
6452 EXPECT_HR(hr, S_OK);
6453
6454 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6455 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6456 if(hfile == INVALID_HANDLE_VALUE) return;
6457
6458 if (hfile != INVALID_HANDLE_VALUE)
6459 {
6460 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6461 ok(read != 0, "could not read file\n");
6462 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6463
6464 CloseHandle(hfile);
6465 DeleteFileA("test.xml");
6466 }
6467
6468 /* save to stream */
6469 V_VT(&dest) = VT_UNKNOWN;
6470 V_UNKNOWN(&dest) = (IUnknown*)&savestream;
6471
6472 hr = IXMLDOMDocument_save(doc, dest);
6473 EXPECT_HR(hr, S_OK);
6474
6475 /* loaded data contains xml declaration */
6476 hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b);
6477 EXPECT_HR(hr, S_OK);
6478
6479 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
6480 ok(hr == S_OK, "got 0x%08x\n", hr);
6481 V_VT(&dest) = VT_UNKNOWN;
6482 V_UNKNOWN(&dest) = (IUnknown*)stream;
6483 hr = IXMLDOMDocument_save(doc, dest);
6484 EXPECT_HR(hr, S_OK);
6485
6486 hr = GetHGlobalFromStream(stream, &global);
6487 EXPECT_HR(hr, S_OK);
6488 ptr = GlobalLock(global);
6489 ok(!memcmp(ptr, win1252decl, strlen(win1252decl)), "got wrong xml declaration\n");
6490 GlobalUnlock(global);
6491 IStream_Release(stream);
6492
6493 /* loaded data without xml declaration */
6494 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b);
6495 EXPECT_HR(hr, S_OK);
6496
6497 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
6498 ok(hr == S_OK, "got 0x%08x\n", hr);
6499 V_VT(&dest) = VT_UNKNOWN;
6500 V_UNKNOWN(&dest) = (IUnknown*)stream;
6501 hr = IXMLDOMDocument_save(doc, dest);
6502 EXPECT_HR(hr, S_OK);
6503
6504 hr = GetHGlobalFromStream(stream, &global);
6505 EXPECT_HR(hr, S_OK);
6506 ptr = GlobalLock(global);
6507 ok(ptr[0] == '<' && ptr[1] != '?', "got wrong start tag %c%c\n", ptr[0], ptr[1]);
6508 GlobalUnlock(global);
6509 IStream_Release(stream);
6510
6511 IXMLDOMDocument_Release(doc);
6512 free_bstrs();
6513 }
6514
6515 static void test_testTransforms(void)
6516 {
6517 IXMLDOMDocument *doc, *docSS;
6518 IXMLDOMNode *pNode;
6519 VARIANT_BOOL bSucc;
6520 HRESULT hr;
6521
6522 doc = create_document(&IID_IXMLDOMDocument);
6523 docSS = create_document(&IID_IXMLDOMDocument);
6524
6525 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
6526 ok(hr == S_OK, "ret %08x\n", hr );
6527
6528 hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
6529 ok(hr == S_OK, "ret %08x\n", hr );
6530
6531 hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
6532 ok(hr == S_OK, "ret %08x\n", hr );
6533 if(hr == S_OK)
6534 {
6535 BSTR bOut;
6536
6537 hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
6538 ok(hr == S_OK, "ret %08x\n", hr );
6539 if(hr == S_OK)
6540 {
6541 ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(bOut));
6542 SysFreeString(bOut);
6543 }
6544
6545 IXMLDOMNode_Release(pNode);
6546 }
6547
6548 IXMLDOMDocument_Release(docSS);
6549 IXMLDOMDocument_Release(doc);
6550
6551 free_bstrs();
6552 }
6553
6554 struct namespaces_change_t {
6555 const CLSID *clsid;
6556 const char *name;
6557 };
6558
6559 static const struct namespaces_change_t namespaces_change_test_data[] = {
6560 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
6561 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
6562 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
6563 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
6564 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
6565 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
6566 { 0 }
6567 };
6568
6569 static void test_namespaces_change(void)
6570 {
6571 const struct namespaces_change_t *class_ptr = namespaces_change_test_data;
6572
6573 while (class_ptr->clsid)
6574 {
6575 IXMLDOMDocument *doc = NULL;
6576 IXMLDOMElement *elem = NULL;
6577 IXMLDOMNode *node = NULL;
6578
6579 VARIANT var;
6580 HRESULT hr;
6581 BSTR str;
6582
6583 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
6584 {
6585 class_ptr++;
6586 continue;
6587 }
6588
6589 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
6590 &IID_IXMLDOMDocument, (void**)&doc);
6591 ok(hr == S_OK, "got 0x%08x\n", hr);
6592
6593 V_VT(&var) = VT_I2;
6594 V_I2(&var) = NODE_ELEMENT;
6595
6596 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
6597 EXPECT_HR(hr, S_OK);
6598
6599 hr = IXMLDOMDocument_appendChild(doc, node, NULL);
6600 EXPECT_HR(hr, S_OK);
6601
6602 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
6603 EXPECT_HR(hr, S_OK);
6604
6605 /* try same prefix, different uri */
6606 V_VT(&var) = VT_BSTR;
6607 V_BSTR(&var) = _bstr_("ns/uri2");
6608
6609 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6610 EXPECT_HR(hr, E_INVALIDARG);
6611
6612 /* try same prefix and uri */
6613 V_VT(&var) = VT_BSTR;
6614 V_BSTR(&var) = _bstr_("ns/uri");
6615
6616 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6617 EXPECT_HR(hr, S_OK);
6618
6619 hr = IXMLDOMElement_get_xml(elem, &str);
6620 EXPECT_HR(hr, S_OK);
6621 ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s for %s\n",
6622 wine_dbgstr_w(str), class_ptr->name);
6623 SysFreeString(str);
6624
6625 IXMLDOMElement_Release(elem);
6626 IXMLDOMDocument_Release(doc);
6627
6628 free_bstrs();
6629
6630 class_ptr++;
6631 }
6632 }
6633
6634 static void test_namespaces_basic(void)
6635 {
6636 static const CHAR namespaces_xmlA[] =
6637 "<?xml version=\"1.0\"?>\n"
6638 "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
6639 " <XMI.content>"
6640 " <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
6641 " </XMI.content>"
6642 "</XMI>";
6643
6644 IXMLDOMDocument *doc;
6645 IXMLDOMElement *elem;
6646 IXMLDOMNode *node;
6647
6648 VARIANT_BOOL b;
6649 HRESULT hr;
6650 BSTR str;
6651
6652 doc = create_document(&IID_IXMLDOMDocument);
6653
6654 hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
6655 EXPECT_HR(hr, S_OK);
6656 ok(b == VARIANT_TRUE, "got %d\n", b);
6657
6658 str = (void *)0xdeadbeef;
6659 hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
6660 EXPECT_HR(hr, S_FALSE);
6661 ok(str == NULL, "got %p\n", str);
6662
6663 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
6664 EXPECT_HR(hr, S_OK);
6665 if(hr == S_OK)
6666 {
6667 IXMLDOMAttribute *attr;
6668 IXMLDOMNode *node2;
6669
6670 hr = IXMLDOMNode_get_firstChild(node, &node2);
6671 EXPECT_HR(hr, S_OK);
6672 ok(node2 != NULL, "got %p\n", node2);
6673
6674 /* Test get_prefix */
6675 hr = IXMLDOMNode_get_prefix(node2, NULL);
6676 EXPECT_HR(hr, E_INVALIDARG);
6677 /* NOTE: Need to test that arg2 gets cleared on Error. */
6678
6679 hr = IXMLDOMNode_get_prefix(node2, &str);
6680 EXPECT_HR(hr, S_OK);
6681 ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
6682 SysFreeString(str);
6683
6684 hr = IXMLDOMNode_get_nodeName(node2, &str);
6685 EXPECT_HR(hr, S_OK);
6686 ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
6687 SysFreeString(str);
6688
6689 /* Test get_namespaceURI */
6690 hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
6691 EXPECT_HR(hr, E_INVALIDARG);
6692 /* NOTE: Need to test that arg2 gets cleared on Error. */
6693
6694 hr = IXMLDOMNode_get_namespaceURI(node2, &str);
6695 EXPECT_HR(hr, S_OK);
6696 ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
6697 SysFreeString(str);
6698
6699 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
6700 EXPECT_HR(hr, S_OK);
6701
6702 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
6703 EXPECT_HR(hr, S_OK);
6704
6705 hr = IXMLDOMAttribute_get_nodeName(attr, &str);
6706 EXPECT_HR(hr, S_OK);
6707 ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
6708 SysFreeString(str);
6709
6710 hr = IXMLDOMAttribute_get_prefix(attr, &str);
6711 EXPECT_HR(hr, S_OK);
6712 ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
6713 SysFreeString(str);
6714
6715 IXMLDOMAttribute_Release(attr);
6716 IXMLDOMElement_Release(elem);
6717
6718 IXMLDOMNode_Release(node2);
6719 IXMLDOMNode_Release(node);
6720 }
6721
6722 IXMLDOMDocument_Release(doc);
6723
6724 free_bstrs();
6725 }
6726
6727 static void test_FormattingXML(void)
6728 {
6729 IXMLDOMDocument *doc;
6730 IXMLDOMElement *pElement;
6731 VARIANT_BOOL bSucc;
6732 HRESULT hr;
6733 BSTR str;
6734 static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
6735 static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
6736
6737 doc = create_document(&IID_IXMLDOMDocument);
6738
6739 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
6740 ok(hr == S_OK, "ret %08x\n", hr );
6741 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6742
6743 if(bSucc == VARIANT_TRUE)
6744 {
6745 hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
6746 ok(hr == S_OK, "ret %08x\n", hr );
6747 if(hr == S_OK)
6748 {
6749 hr = IXMLDOMElement_get_xml(pElement, &str);
6750 ok(hr == S_OK, "ret %08x\n", hr );
6751 ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
6752 SysFreeString(str);
6753
6754 IXMLDOMElement_Release(pElement);
6755 }
6756 }
6757
6758 IXMLDOMDocument_Release(doc);
6759
6760 free_bstrs();
6761 }
6762
6763 typedef struct _nodetypedvalue_t {
6764 const char *name;
6765 VARTYPE type;
6766 const char *value; /* value in string format */
6767 } nodetypedvalue_t;
6768
6769 static const nodetypedvalue_t get_nodetypedvalue[] = {
6770 { "root/string", VT_BSTR, "Wine" },
6771 { "root/string2", VT_BSTR, "String" },
6772 { "root/number", VT_BSTR, "12.44" },
6773 { "root/number2", VT_BSTR, "-3.71e3" },
6774 { "root/int", VT_I4, "-13" },
6775 { "root/fixed", VT_CY, "7322.9371" },
6776 { "root/bool", VT_BOOL, "-1" },
6777 { "root/datetime", VT_DATE, "40135.14" },
6778 { "root/datetimetz",VT_DATE, "37813.59" },
6779 { "root/date", VT_DATE, "665413" },
6780 { "root/time", VT_DATE, "0.5813889" },
6781 { "root/timetz", VT_DATE, "1.112512" },
6782 { "root/i1", VT_I1, "-13" },
6783 { "root/i2", VT_I2, "31915" },
6784 { "root/i4", VT_I4, "-312232" },
6785 { "root/ui1", VT_UI1, "123" },
6786 { "root/ui2", VT_UI2, "48282" },
6787 { "root/ui4", VT_UI4, "949281" },
6788 { "root/r4", VT_R4, "213124" },
6789 { "root/r8", VT_R8, "0.412" },
6790 { "root/float", VT_R8, "41221.421" },
6791 { "root/uuid", VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
6792 { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
6793 { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
6794 { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
6795 { 0 }
6796 };
6797
6798 static void test_nodeTypedValue(void)
6799 {
6800 const nodetypedvalue_t *entry = get_nodetypedvalue;
6801 IXMLDOMDocumentType *doctype, *doctype2;
6802 IXMLDOMProcessingInstruction *pi;
6803 IXMLDOMDocumentFragment *frag;
6804 IXMLDOMDocument *doc, *doc2;
6805 IXMLDOMCDATASection *cdata;
6806 IXMLDOMComment *comment;
6807 IXMLDOMNode *node;
6808 VARIANT_BOOL b;
6809 VARIANT value;
6810 HRESULT hr;
6811
6812 doc = create_document(&IID_IXMLDOMDocument);
6813
6814 b = VARIANT_FALSE;
6815 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
6816 ok(hr == S_OK, "ret %08x\n", hr );
6817 ok(b == VARIANT_TRUE, "got %d\n", b);
6818
6819 hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
6820 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6821
6822 V_VT(&value) = VT_BSTR;
6823 V_BSTR(&value) = NULL;
6824 hr = IXMLDOMDocument_get_nodeValue(doc, &value);
6825 ok(hr == S_FALSE, "ret %08x\n", hr );
6826 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
6827
6828 hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
6829 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6830
6831 V_VT(&value) = VT_EMPTY;
6832 hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
6833 ok(hr == S_FALSE, "ret %08x\n", hr );
6834 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6835
6836 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
6837 ok(hr == S_OK, "ret %08x\n", hr );
6838
6839 V_VT(&value) = VT_BSTR;
6840 V_BSTR(&value) = NULL;
6841 hr = IXMLDOMNode_get_nodeValue(node, &value);
6842 ok(hr == S_FALSE, "ret %08x\n", hr );
6843 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
6844
6845 hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
6846 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6847
6848 IXMLDOMNode_Release(node);
6849
6850 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
6851 ok(hr == S_OK, "ret %08x\n", hr );
6852 {
6853 BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
6854
6855 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
6856 ok(hr == S_OK, "ret %08x\n", hr );
6857 ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
6858 ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
6859 if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
6860 ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
6861 VariantClear(&value);
6862 IXMLDOMNode_Release(node);
6863 }
6864
6865 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
6866 ok(hr == S_OK, "ret %08x\n", hr );
6867 {
6868 V_VT(&value) = VT_NULL;
6869 V_BSTR(&value) = (void*)0xdeadbeef;
6870 hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
6871 ok(hr == S_OK, "ret %08x\n", hr );
6872 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6873 ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
6874 IXMLDOMProcessingInstruction_Release(pi);
6875 VariantClear(&value);
6876 }
6877
6878 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
6879 ok(hr == S_OK, "ret %08x\n", hr );
6880 {
6881 V_VT(&value) = VT_NULL;
6882 V_BSTR(&value) = (void*)0xdeadbeef;
6883 hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
6884 ok(hr == S_OK, "ret %08x\n", hr );
6885 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6886 ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
6887 IXMLDOMCDATASection_Release(cdata);
6888 VariantClear(&value);
6889 }
6890
6891 hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
6892 ok(hr == S_OK, "ret %08x\n", hr );
6893 {
6894 V_VT(&value) = VT_NULL;
6895 V_BSTR(&value) = (void*)0xdeadbeef;
6896 hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
6897 ok(hr == S_OK, "ret %08x\n", hr );
6898 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6899 ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
6900 IXMLDOMComment_Release(comment);
6901 VariantClear(&value);
6902 }
6903
6904 hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
6905 ok(hr == S_OK, "ret %08x\n", hr );
6906 {
6907 V_VT(&value) = VT_EMPTY;
6908 hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
6909 ok(hr == S_FALSE, "ret %08x\n", hr );
6910 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6911 IXMLDOMDocumentFragment_Release(frag);
6912 }
6913
6914 doc2 = create_document(&IID_IXMLDOMDocument);
6915
6916 b = VARIANT_FALSE;
6917 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
6918 ok(hr == S_OK, "ret %08x\n", hr );
6919 ok(b == VARIANT_TRUE, "got %d\n", b);
6920
6921 EXPECT_REF(doc2, 1);
6922
6923 hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
6924 ok(hr == S_OK, "ret %08x\n", hr );
6925
6926 EXPECT_REF(doc2, 1);
6927 todo_wine EXPECT_REF(doctype, 2);
6928
6929 {
6930 V_VT(&value) = VT_EMPTY;
6931 hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
6932 ok(hr == S_FALSE, "ret %08x\n", hr );
6933 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6934 }
6935
6936 hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
6937 ok(hr == S_OK, "ret %08x\n", hr );
6938 ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
6939
6940 IXMLDOMDocumentType_Release(doctype2);
6941 IXMLDOMDocumentType_Release(doctype);
6942
6943 IXMLDOMDocument_Release(doc2);
6944
6945 while (entry->name)
6946 {
6947 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
6948 ok(hr == S_OK, "ret %08x\n", hr );
6949
6950 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
6951 ok(hr == S_OK, "ret %08x\n", hr );
6952 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
6953
6954 if (entry->type == (VT_ARRAY|VT_UI1))
6955 {
6956 ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
6957 "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
6958 }
6959
6960 if (entry->type != VT_BSTR)
6961 {
6962 if (entry->type == VT_DATE ||
6963 entry->type == VT_R8 ||
6964 entry->type == VT_CY)
6965 {
6966 if (entry->type == VT_DATE)
6967 {
6968 hr = VariantChangeType(&value, &value, 0, VT_R4);
6969 ok(hr == S_OK, "ret %08x\n", hr );
6970 }
6971 hr = VariantChangeTypeEx(&value, &value,
6972 MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
6973 VARIANT_NOUSEROVERRIDE, VT_BSTR);
6974 ok(hr == S_OK, "ret %08x\n", hr );
6975 }
6976 else
6977 {
6978 hr = VariantChangeType(&value, &value, 0, VT_BSTR);
6979 ok(hr == S_OK, "ret %08x\n", hr );
6980 }
6981
6982 /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
6983 if (entry->type == (VT_ARRAY|VT_UI1))
6984 {
6985 ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
6986 "expected %s\n", entry->value);
6987 }
6988 else
6989 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6990 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6991 }
6992 else
6993 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6994 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6995
6996 VariantClear( &value );
6997 IXMLDOMNode_Release(node);
6998
6999 entry++;
7000 }
7001
7002 IXMLDOMDocument_Release(doc);
7003 free_bstrs();
7004 }
7005
7006 static void test_TransformWithLoadingLocalFile(void)
7007 {
7008 IXMLDOMDocument *doc;
7009 IXMLDOMDocument *xsl;
7010 IXMLDOMNode *pNode;
7011 VARIANT_BOOL bSucc;
7012 HRESULT hr;
7013 HANDLE file;
7014 DWORD dwWritten;
7015 char lpPathBuffer[MAX_PATH];
7016 int i;
7017
7018 /* Create a Temp File. */
7019 GetTempPathA(MAX_PATH, lpPathBuffer);
7020 strcat(lpPathBuffer, "customers.xml" );
7021
7022 file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7023 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7024 if(file == INVALID_HANDLE_VALUE)
7025 return;
7026
7027 WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7028 CloseHandle(file);
7029
7030 /* Correct path to not include an escape character. */
7031 for(i=0; i < strlen(lpPathBuffer); i++)
7032 {
7033 if(lpPathBuffer[i] == '\\')
7034 lpPathBuffer[i] = '/';
7035 }
7036
7037 doc = create_document(&IID_IXMLDOMDocument);
7038 xsl = create_document(&IID_IXMLDOMDocument);
7039
7040 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7041 ok(hr == S_OK, "ret %08x\n", hr );
7042 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7043 if(bSucc == VARIANT_TRUE)
7044 {
7045 BSTR sXSL;
7046 BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7047 BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7048 BSTR sFileName = _bstr_(lpPathBuffer);
7049 int nLength = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7050
7051 sXSL = SysAllocStringLen(NULL, nLength);
7052 lstrcpyW(sXSL, sPart1);
7053 lstrcatW(sXSL, sFileName);
7054 lstrcatW(sXSL, sPart2);
7055
7056 hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7057 ok(hr == S_OK, "ret %08x\n", hr );
7058 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7059 if(bSucc == VARIANT_TRUE)
7060 {
7061 BSTR sResult;
7062
7063 hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7064 ok(hr == S_OK, "ret %08x\n", hr );
7065 if(hr == S_OK)
7066 {
7067 /* This will load the temp file via the XSL */
7068 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7069 ok(hr == S_OK, "ret %08x\n", hr );
7070 if(hr == S_OK)
7071 {
7072 ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7073 SysFreeString(sResult);
7074 }
7075
7076 IXMLDOMNode_Release(pNode);
7077 }
7078 }
7079
7080 SysFreeString(sXSL);
7081 }
7082
7083 IXMLDOMDocument_Release(doc);
7084 IXMLDOMDocument_Release(xsl);
7085
7086 DeleteFileA(lpPathBuffer);
7087 free_bstrs();
7088 }
7089
7090 static void test_put_nodeValue(void)
7091 {
7092 static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7093 IXMLDOMDocument *doc;
7094 IXMLDOMText *text;
7095 IXMLDOMEntityReference *entityref;
7096 IXMLDOMAttribute *attr;
7097 IXMLDOMNode *node;
7098 HRESULT hr;
7099 VARIANT data, type;
7100
7101 doc = create_document(&IID_IXMLDOMDocument);
7102
7103 /* test for unsupported types */
7104 /* NODE_DOCUMENT */
7105 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7106 ok(hr == S_OK, "ret %08x\n", hr );
7107 V_VT(&data) = VT_BSTR;
7108 V_BSTR(&data) = _bstr_("one two three");
7109 hr = IXMLDOMNode_put_nodeValue(node, data);
7110 ok(hr == E_FAIL, "ret %08x\n", hr );
7111 IXMLDOMNode_Release(node);
7112
7113 /* NODE_DOCUMENT_FRAGMENT */
7114 V_VT(&type) = VT_I1;
7115 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7116 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7117 ok(hr == S_OK, "ret %08x\n", hr );
7118 V_VT(&data) = VT_BSTR;
7119 V_BSTR(&data) = _bstr_("one two three");
7120 hr = IXMLDOMNode_put_nodeValue(node, data);
7121 ok(hr == E_FAIL, "ret %08x\n", hr );
7122 IXMLDOMNode_Release(node);
7123
7124 /* NODE_ELEMENT */
7125 V_VT(&type) = VT_I1;
7126 V_I1(&type) = NODE_ELEMENT;
7127 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7128 ok(hr == S_OK, "ret %08x\n", hr );
7129 V_VT(&data) = VT_BSTR;
7130 V_BSTR(&data) = _bstr_("one two three");
7131 hr = IXMLDOMNode_put_nodeValue(node, data);
7132 ok(hr == E_FAIL, "ret %08x\n", hr );
7133 IXMLDOMNode_Release(node);
7134
7135 /* NODE_ENTITY_REFERENCE */
7136 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7137 ok(hr == S_OK, "ret %08x\n", hr );
7138
7139 V_VT(&data) = VT_BSTR;
7140 V_BSTR(&data) = _bstr_("one two three");
7141 hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7142 ok(hr == E_FAIL, "ret %08x\n", hr );
7143
7144 hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7145 ok(hr == S_OK, "ret %08x\n", hr );
7146 V_VT(&data) = VT_BSTR;
7147 V_BSTR(&data) = _bstr_("one two three");
7148 hr = IXMLDOMNode_put_nodeValue(node, data);
7149 ok(hr == E_FAIL, "ret %08x\n", hr );
7150 IXMLDOMNode_Release(node);
7151 IXMLDOMEntityReference_Release(entityref);
7152
7153 /* supported types */
7154 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7155 ok(hr == S_OK, "ret %08x\n", hr );
7156 V_VT(&data) = VT_BSTR;
7157 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7158 hr = IXMLDOMText_put_nodeValue(text, data);
7159 ok(hr == S_OK, "ret %08x\n", hr );
7160 IXMLDOMText_Release(text);
7161
7162 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7163 ok(hr == S_OK, "ret %08x\n", hr );
7164 V_VT(&data) = VT_BSTR;
7165 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7166 hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7167 ok(hr == S_OK, "ret %08x\n", hr );
7168 hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7169 ok(hr == S_OK, "ret %08x\n", hr );
7170 ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7171 wine_dbgstr_w(V_BSTR(&data)));
7172 VariantClear(&data);
7173 IXMLDOMAttribute_Release(attr);
7174
7175 free_bstrs();
7176
7177 IXMLDOMDocument_Release(doc);
7178 }
7179
7180 static void test_IObjectSafety(void)
7181 {
7182 IXMLDOMDocument *doc;
7183 IObjectSafety *safety;
7184 HRESULT hr;
7185
7186 doc = create_document(&IID_IXMLDOMDocument);
7187
7188 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7189 ok(hr == S_OK, "ret %08x\n", hr );
7190
7191 test_IObjectSafety_common(safety);
7192
7193 IObjectSafety_Release(safety);
7194 IXMLDOMDocument_Release(doc);
7195
7196 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
7197 &IID_IObjectSafety, (void**)&safety);
7198 ok(hr == S_OK, "Could not create XMLHTTPRequest instance: %08x\n", hr);
7199
7200 test_IObjectSafety_common(safety);
7201
7202 IObjectSafety_Release(safety);
7203
7204 }
7205
7206 typedef struct _property_test_t {
7207 const GUID *guid;
7208 const char *clsid;
7209 const char *property;
7210 const char *value;
7211 } property_test_t;
7212
7213 static const property_test_t properties_test_data[] = {
7214 { &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7215 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7216 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7217 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7218 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7219 { 0 }
7220 };
7221
7222 static void test_default_properties(void)
7223 {
7224 const property_test_t *entry = properties_test_data;
7225
7226 while (entry->guid)
7227 {
7228 IXMLDOMDocument2 *doc;
7229 VARIANT var;
7230 HRESULT hr;
7231
7232 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
7233 {
7234 entry++;
7235 continue;
7236 }
7237
7238 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7239 ok(hr == S_OK, "got 0x%08x\n", hr);
7240
7241 hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7242 ok(hr == S_OK, "got 0x%08x\n", hr);
7243 ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7244 entry->value, entry->clsid);
7245 VariantClear(&var);
7246
7247 IXMLDOMDocument2_Release(doc);
7248
7249 entry++;
7250 }
7251 }
7252
7253 typedef struct {
7254 const char *query;
7255 const char *list;
7256 BOOL todo;
7257 } xslpattern_test_t;
7258
7259 static const xslpattern_test_t xslpattern_test[] = {
7260 { "root//elem[0]", "E1.E2.D1" },
7261 { "root//elem[index()=1]", "E2.E2.D1" },
7262 { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7263 { "root//elem[end()]", "E4.E2.D1" },
7264 { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7265 { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7266 { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7267 { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7268 { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7269 { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7270 { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7271 { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7272 { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7273 { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7274 { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7275 { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7276 { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7277 { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7278 { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7279 { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7280 { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7281 { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7282 { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7283 { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7284 { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7285 { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7286 { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7287 { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7288 { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7289 { "root/elem[0]", "E1.E2.D1" },
7290 { "root/elem[index()=1]", "E2.E2.D1" },
7291 { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7292 { "root/elem[end()]", "E4.E2.D1" },
7293 { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7294 { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7295 { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7296 { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7297 { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7298 { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7299 { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7300 { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7301 { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7302 { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7303 { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7304 { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7305 { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7306 { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7307 { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7308 { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7309 { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7310 { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7311 { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7312 { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7313 { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7314 { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7315 { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7316 { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7317 { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7318 { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7319 { "root/elem[@*]", "E2.E2.D1 E3.E2.D1", TRUE },
7320 { NULL }
7321 };
7322
7323 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7324 /* prefixes don't need to be registered, you may use them as they are in the doc */
7325 { "//bar:x", "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7326 /* prefixes must be explicitly specified in the name */
7327 { "//foo:elem", "" },
7328 { "//foo:c", "E3.E4.E2.D1" },
7329 { NULL }
7330 };
7331
7332 static const xslpattern_test_t xslpattern_test_func[] = {
7333 { "attribute()", "" },
7334 { "attribute('depth')", "" },
7335 { "root/attribute('depth')", "A'depth'.E3.D1" },
7336 { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7337 { "//x//attribute(id)", NULL },
7338 { "//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" },
7339 { "comment()", "C2.D1" },
7340 { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7341 { "element()", "E3.D1" },
7342 { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7343 { "//element(a)", NULL },
7344 { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7345 { "node()", "P1.D1 C2.D1 E3.D1" },
7346 { "//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" },
7347 { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7348 { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7349 { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7350 { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7351 { "pi()", "P1.D1" },
7352 { "//y/pi()", "P1.E4.E3.D1" },
7353 { "root/textnode()", "T2.E3.D1" },
7354 { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7355 { NULL }
7356 };
7357
7358 static void test_XSLPattern(void)
7359 {
7360 const xslpattern_test_t *ptr = xslpattern_test;
7361 IXMLDOMDocument2 *doc;
7362 IXMLDOMNodeList *list;
7363 VARIANT_BOOL b;
7364 HRESULT hr;
7365 LONG len;
7366
7367 doc = create_document(&IID_IXMLDOMDocument2);
7368
7369 b = VARIANT_FALSE;
7370 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7371 EXPECT_HR(hr, S_OK);
7372 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7373
7374 /* switch to XSLPattern */
7375 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7376 EXPECT_HR(hr, S_OK);
7377
7378 /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7379 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7380 EXPECT_HR(hr, S_OK);
7381
7382 len = 0;
7383 hr = IXMLDOMNodeList_get_length(list, &len);
7384 EXPECT_HR(hr, S_OK);
7385 /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7386 ok(len == 3, "expected 3 entries in list, got %d\n", len);
7387 IXMLDOMNodeList_Release(list);
7388
7389 while (ptr->query)
7390 {
7391 list = NULL;
7392 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7393 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7394 len = 0;
7395 hr = IXMLDOMNodeList_get_length(list, &len);
7396 ok(len != 0, "query=%s, empty list\n", ptr->query);
7397 if (len) {
7398 if (ptr->todo) {
7399 char *str = list_to_string(list);
7400 todo_wine
7401 ok(!strcmp(str, ptr->list), "Invalid node list: %s, expected %s\n", str, ptr->list);
7402 IXMLDOMNodeList_Release(list);
7403 }
7404 else
7405 expect_list_and_release(list, ptr->list);
7406 }
7407
7408 ptr++;
7409 }
7410
7411 /* namespace handling */
7412 /* no registered namespaces */
7413 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7414 EXPECT_HR(hr, S_OK);
7415
7416 ptr = xslpattern_test_no_ns;
7417 while (ptr->query)
7418 {
7419 list = NULL;
7420 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7421 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7422
7423 if (*ptr->list)
7424 {
7425 len = 0;
7426 hr = IXMLDOMNodeList_get_length(list, &len);
7427 EXPECT_HR(hr, S_OK);
7428 ok(len != 0, "query=%s, empty list\n", ptr->query);
7429 }
7430 else
7431 {
7432 len = 1;
7433 hr = IXMLDOMNodeList_get_length(list, &len);
7434 EXPECT_HR(hr, S_OK);
7435 ok(len == 0, "query=%s, empty list\n", ptr->query);
7436 }
7437 if (len)
7438 expect_list_and_release(list, ptr->list);
7439
7440 ptr++;
7441 }
7442
7443 /* explicitly register prefix foo */
7444 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7445
7446 /* now we get the same behavior as XPath */
7447 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7448 EXPECT_HR(hr, S_OK);
7449 len = 0;
7450 hr = IXMLDOMNodeList_get_length(list, &len);
7451 EXPECT_HR(hr, S_OK);
7452 ok(len != 0, "expected filled list\n");
7453 if (len)
7454 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
7455
7456 /* set prefix foo to some nonexistent namespace */
7457 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
7458 EXPECT_HR(hr, S_OK);
7459
7460 /* the registered prefix takes precedence */
7461 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7462 EXPECT_HR(hr, S_OK);
7463 len = 0;
7464 hr = IXMLDOMNodeList_get_length(list, &len);
7465 EXPECT_HR(hr, S_OK);
7466 ok(len == 0, "expected empty list\n");
7467 IXMLDOMNodeList_Release(list);
7468
7469 IXMLDOMDocument2_Release(doc);
7470
7471 doc = create_document(&IID_IXMLDOMDocument2);
7472
7473 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
7474 EXPECT_HR(hr, S_OK);
7475 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7476
7477 ptr = xslpattern_test_func;
7478 while (ptr->query)
7479 {
7480 list = NULL;
7481 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7482 if (ptr->list)
7483 {
7484 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7485 len = 0;
7486 hr = IXMLDOMNodeList_get_length(list, &len);
7487 ok(hr == S_OK, "Failed to get list length, hr %#x.\n", hr);
7488 if (*ptr->list)
7489 {
7490 ok(len != 0, "query=%s, empty list\n", ptr->query);
7491 if (len)
7492 expect_list_and_release(list, ptr->list);
7493 }
7494 else
7495 ok(len == 0, "query=%s, filled list\n", ptr->query);
7496 }
7497 else
7498 ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7499
7500 ptr++;
7501 }
7502
7503 IXMLDOMDocument2_Release(doc);
7504 free_bstrs();
7505 }
7506
7507 static void test_splitText(void)
7508 {
7509 IXMLDOMCDATASection *cdata;
7510 IXMLDOMElement *root;
7511 IXMLDOMDocument *doc;
7512 IXMLDOMText *text, *text2;
7513 IXMLDOMNode *node;
7514 VARIANT var;
7515 VARIANT_BOOL success;
7516 LONG length;
7517 HRESULT hr;
7518
7519 doc = create_document(&IID_IXMLDOMDocument);
7520
7521 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
7522 ok(hr == S_OK, "got 0x%08x\n", hr);
7523
7524 hr = IXMLDOMDocument_get_documentElement(doc, &root);
7525 ok(hr == S_OK, "got 0x%08x\n", hr);
7526
7527 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
7528 ok(hr == S_OK, "got 0x%08x\n", hr);
7529
7530 V_VT(&var) = VT_EMPTY;
7531 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
7532 ok(hr == S_OK, "got 0x%08x\n", hr);
7533
7534 length = 0;
7535 hr = IXMLDOMCDATASection_get_length(cdata, &length);
7536 ok(hr == S_OK, "got 0x%08x\n", hr);
7537 ok(length > 0, "got %d\n", length);
7538
7539 hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
7540 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7541
7542 text = (void*)0xdeadbeef;
7543 /* negative offset */
7544 hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
7545 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7546 ok(text == (void*)0xdeadbeef, "got %p\n", text);
7547
7548 text = (void*)0xdeadbeef;
7549 /* offset outside data */
7550 hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
7551 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7552 ok(text == 0, "got %p\n", text);
7553
7554 text = (void*)0xdeadbeef;
7555 /* offset outside data */
7556 hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
7557 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7558 ok(text == 0, "got %p\n", text);
7559
7560 /* no empty node created */
7561 node = (void*)0xdeadbeef;
7562 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7563 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7564 ok(node == 0, "got %p\n", text);
7565
7566 hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
7567 ok(hr == S_OK, "got 0x%08x\n", hr);
7568
7569 length = 0;
7570 hr = IXMLDOMText_get_length(text, &length);
7571 ok(hr == S_OK, "got 0x%08x\n", hr);
7572 ok(length == 7, "got %d\n", length);
7573
7574 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7575 ok(hr == S_OK, "got 0x%08x\n", hr);
7576 IXMLDOMNode_Release(node);
7577
7578 /* split new text node */
7579 hr = IXMLDOMText_get_length(text, &length);
7580 ok(hr == S_OK, "got 0x%08x\n", hr);
7581
7582 node = (void*)0xdeadbeef;
7583 hr = IXMLDOMText_get_nextSibling(text, &node);
7584 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7585 ok(node == 0, "got %p\n", text);
7586
7587 hr = IXMLDOMText_splitText(text, 0, NULL);
7588 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7589
7590 text2 = (void*)0xdeadbeef;
7591 /* negative offset */
7592 hr = IXMLDOMText_splitText(text, -1, &text2);
7593 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7594 ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
7595
7596 text2 = (void*)0xdeadbeef;
7597 /* offset outside data */
7598 hr = IXMLDOMText_splitText(text, length + 1, &text2);
7599 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7600 ok(text2 == 0, "got %p\n", text2);
7601
7602 text2 = (void*)0xdeadbeef;
7603 /* offset outside data */
7604 hr = IXMLDOMText_splitText(text, length, &text2);
7605 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7606 ok(text2 == 0, "got %p\n", text);
7607
7608 text2 = 0;
7609 hr = IXMLDOMText_splitText(text, 4, &text2);
7610 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7611 if (text2) IXMLDOMText_Release(text2);
7612
7613 node = 0;
7614 hr = IXMLDOMText_get_nextSibling(text, &node);
7615 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7616 if (node) IXMLDOMNode_Release(node);
7617
7618 IXMLDOMText_Release(text);
7619 IXMLDOMElement_Release(root);
7620 IXMLDOMCDATASection_Release(cdata);
7621 free_bstrs();
7622 }
7623
7624 typedef struct {
7625 const char *name;
7626 const char *uri;
7627 HRESULT hr;
7628 } ns_item_t;
7629
7630 /* default_ns_doc used */
7631 static const ns_item_t qualified_item_tests[] = {
7632 { "xml:lang", NULL, S_FALSE },
7633 { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
7634 { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
7635 { "ns:b", NULL, S_FALSE },
7636 { "ns:b", "nshref", S_FALSE },
7637 { "b", "nshref", S_OK },
7638 { "d", NULL, S_OK },
7639 { NULL }
7640 };
7641
7642 static const ns_item_t named_item_tests[] = {
7643 { "xml:lang", NULL, S_OK },
7644 { "lang", NULL, S_FALSE },
7645 { "ns:b", NULL, S_OK },
7646 { "b", NULL, S_FALSE },
7647 { "d", NULL, S_OK },
7648 { NULL }
7649 };
7650
7651 static void test_getQualifiedItem(void)
7652 {
7653 IXMLDOMNode *pr_node, *node;
7654 IXMLDOMNodeList *root_list;
7655 IXMLDOMNamedNodeMap *map;
7656 IXMLDOMElement *element;
7657 const ns_item_t* ptr;
7658 IXMLDOMDocument *doc;
7659 VARIANT_BOOL b;
7660 HRESULT hr;
7661 LONG len;
7662
7663 doc = create_document(&IID_IXMLDOMDocument);
7664
7665 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
7666 EXPECT_HR(hr, S_OK);
7667 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7668
7669 hr = IXMLDOMDocument_get_documentElement(doc, &element);
7670 EXPECT_HR(hr, S_OK);
7671
7672 hr = IXMLDOMElement_get_childNodes(element, &root_list);
7673 EXPECT_HR(hr, S_OK);
7674
7675 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
7676 EXPECT_HR(hr, S_OK);
7677 IXMLDOMNodeList_Release(root_list);
7678
7679 hr = IXMLDOMNode_get_attributes(pr_node, &map);
7680 EXPECT_HR(hr, S_OK);
7681 IXMLDOMNode_Release(pr_node);
7682
7683 len = 0;
7684 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7685 EXPECT_HR(hr, S_OK);
7686 ok( len == 3, "length %d\n", len);
7687
7688 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
7689 EXPECT_HR(hr, E_INVALIDARG);
7690
7691 node = (void*)0xdeadbeef;
7692 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
7693 EXPECT_HR(hr, E_INVALIDARG);
7694 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7695
7696 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
7697 EXPECT_HR(hr, E_INVALIDARG);
7698
7699 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
7700 EXPECT_HR(hr, S_OK);
7701
7702 IXMLDOMNode_Release(node);
7703 IXMLDOMNamedNodeMap_Release(map);
7704 IXMLDOMElement_Release(element);
7705
7706 hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
7707 EXPECT_HR(hr, S_OK);
7708
7709 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
7710 EXPECT_HR(hr, S_OK);
7711
7712 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
7713 EXPECT_HR(hr, S_OK);
7714 IXMLDOMNode_Release(node);
7715
7716 hr = IXMLDOMElement_get_attributes(element, &map);
7717 EXPECT_HR(hr, S_OK);
7718
7719 ptr = qualified_item_tests;
7720 while (ptr->name)
7721 {
7722 node = (void*)0xdeadbeef;
7723 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
7724 ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
7725 if (hr == S_OK)
7726 IXMLDOMNode_Release(node);
7727 else
7728 ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
7729 ptr++;
7730 }
7731
7732 ptr = named_item_tests;
7733 while (ptr->name)
7734 {
7735 node = (void*)0xdeadbeef;
7736 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
7737 ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
7738 if (hr == S_OK)
7739 IXMLDOMNode_Release(node);
7740 else
7741 ok(node == NULL, "%s: got %p\n", ptr->name, node);
7742 ptr++;
7743 }
7744
7745 IXMLDOMNamedNodeMap_Release(map);
7746
7747 IXMLDOMElement_Release(element);
7748 IXMLDOMDocument_Release(doc);
7749 free_bstrs();
7750 }
7751
7752 static void test_removeQualifiedItem(void)
7753 {
7754 IXMLDOMDocument *doc;
7755 IXMLDOMElement *element;
7756 IXMLDOMNode *pr_node, *node;
7757 IXMLDOMNodeList *root_list;
7758 IXMLDOMNamedNodeMap *map;
7759 VARIANT_BOOL b;
7760 LONG len;
7761 HRESULT hr;
7762
7763 doc = create_document(&IID_IXMLDOMDocument);
7764
7765 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
7766 ok( hr == S_OK, "loadXML failed\n");
7767 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7768
7769 hr = IXMLDOMDocument_get_documentElement(doc, &element);
7770 ok( hr == S_OK, "ret %08x\n", hr);
7771
7772 hr = IXMLDOMElement_get_childNodes(element, &root_list);
7773 ok( hr == S_OK, "ret %08x\n", hr);
7774
7775 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
7776 ok( hr == S_OK, "ret %08x\n", hr);
7777 IXMLDOMNodeList_Release(root_list);
7778
7779 hr = IXMLDOMNode_get_attributes(pr_node, &map);
7780 ok( hr == S_OK, "ret %08x\n", hr);
7781 IXMLDOMNode_Release(pr_node);
7782
7783 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7784 ok( hr == S_OK, "ret %08x\n", hr);
7785 ok( len == 3, "length %d\n", len);
7786
7787 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
7788 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7789
7790 node = (void*)0xdeadbeef;
7791 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
7792 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7793 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7794
7795 /* out pointer is optional */
7796 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7797 ok( hr == S_OK, "ret %08x\n", hr);
7798
7799 /* already removed */
7800 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7801 ok( hr == S_FALSE, "ret %08x\n", hr);
7802
7803 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
7804 ok( hr == S_OK, "ret %08x\n", hr);
7805 IXMLDOMNode_Release(node);
7806
7807 IXMLDOMNamedNodeMap_Release( map );
7808 IXMLDOMElement_Release( element );
7809 IXMLDOMDocument_Release( doc );
7810 free_bstrs();
7811 }
7812
7813 #define check_default_props(doc) _check_default_props(__LINE__, doc)
7814 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
7815 {
7816 VARIANT_BOOL b;
7817 VARIANT var;
7818 HRESULT hr;
7819
7820 VariantInit(&var);
7821 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7822 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
7823 VariantClear(&var);
7824
7825 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7826 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
7827 VariantClear(&var);
7828
7829 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7830 ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
7831
7832 hr = IXMLDOMDocument2_get_schemas(doc, &var);
7833 ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
7834 VariantClear(&var);
7835 }
7836
7837 #define check_set_props(doc) _check_set_props(__LINE__, doc)
7838 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
7839 {
7840 VARIANT_BOOL b;
7841 VARIANT var;
7842
7843 VariantInit(&var);
7844 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7845 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
7846 VariantClear(&var);
7847
7848 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7849 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
7850 VariantClear(&var);
7851
7852 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7853 ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
7854
7855 helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
7856 ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
7857 VariantClear(&var);
7858 }
7859
7860 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
7861 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
7862 {
7863 VARIANT var;
7864
7865 VariantInit(&var);
7866 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
7867 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
7868 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
7869 V_VT(&var) = VT_DISPATCH;
7870 V_DISPATCH(&var) = NULL;
7871 helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
7872 ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
7873 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7874 VariantClear(&var);
7875 }
7876
7877 #define unset_props(doc) _unset_props(__LINE__, doc)
7878 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
7879 {
7880 VARIANT var;
7881
7882 VariantInit(&var);
7883 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
7884 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
7885 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
7886 V_VT(&var) = VT_NULL;
7887 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7888 VariantClear(&var);
7889 }
7890
7891 static void test_get_ownerDocument(void)
7892 {
7893 IXMLDOMDocument *doc1, *doc2, *doc3;
7894 IXMLDOMDocument2 *doc, *doc_owner;
7895 IXMLDOMNode *node;
7896 IXMLDOMSchemaCollection *cache;
7897 VARIANT_BOOL b;
7898 VARIANT var;
7899 IXMLDOMElement *element;
7900 IXMLDOMNodeList *node_list;
7901 IXMLDOMAttribute *attr;
7902 LONG i, len;
7903 HRESULT hr;
7904 const CHAR nodeXML[] =
7905 "<root id='0'>"
7906 " <!-- comment node 0 -->"
7907 " text node 0"
7908 " <x attr='val'></x>"
7909 " <?foo value='PI for x'?>"
7910 " <![CDATA[ cdata ]]>"
7911 "</root>";
7912
7913 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
7914 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
7915
7916 doc = create_document(&IID_IXMLDOMDocument2);
7917 cache = create_cache(&IID_IXMLDOMSchemaCollection);
7918
7919 VariantInit(&var);
7920
7921 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
7922 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7923
7924 check_default_props(doc);
7925
7926 /* set properties and check that new instances use them */
7927 set_props(doc, cache);
7928 check_set_props(doc);
7929
7930 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7931 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
7932
7933 /* new interface keeps props */
7934 ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7935 ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
7936 check_set_props(doc_owner);
7937 IXMLDOMDocument2_Release(doc_owner);
7938
7939 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
7940 IXMLDOMNode_Release(node);
7941
7942 ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
7943
7944 /* reload */
7945 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
7946 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7947
7948 /* properties retained even after reload */
7949 check_set_props(doc);
7950
7951 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7952 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
7953 IXMLDOMNode_Release(node);
7954
7955 ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7956 ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
7957 check_set_props(doc_owner);
7958
7959 /* changing properties for one instance changes them for all */
7960 unset_props(doc_owner);
7961 check_default_props(doc_owner);
7962 check_default_props(doc);
7963
7964 /* NULL check */
7965 hr = IXMLDOMDocument_loadXML(doc1, _bstr_(nodeXML), &b);
7966 EXPECT_HR(hr, S_OK);
7967 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7968
7969 hr = IXMLDOMDocument_get_documentElement(doc1, &element);
7970 EXPECT_HR(hr, S_OK);
7971
7972 hr = IXMLDOMElement_get_childNodes(element, &node_list);
7973 EXPECT_HR(hr, S_OK);
7974
7975 hr = IXMLDOMNodeList_get_length(node_list, &len);
7976 EXPECT_HR(hr, S_OK);
7977
7978 for(i = 0; i < len; i++) {
7979 hr = IXMLDOMNodeList_get_item(node_list, i, &node);
7980 EXPECT_HR(hr, S_OK);
7981
7982 hr = IXMLDOMNode_get_ownerDocument(node, NULL);
7983 EXPECT_HR(hr, E_INVALIDARG);
7984
7985 IXMLDOMNode_Release(node);
7986 }
7987 IXMLDOMElement_Release(element);
7988
7989 /* Test Attribute Node */
7990 hr = IXMLDOMNodeList_get_item(node_list, 2, &node);
7991 EXPECT_HR(hr, S_OK);
7992 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
7993 EXPECT_HR(hr, S_OK);
7994 IXMLDOMNode_Release(node);
7995
7996 hr = IXMLDOMElement_getAttributeNode(element, _bstr_("attr"), &attr);
7997 EXPECT_HR(hr, S_OK);
7998 ok(attr != NULL, "attr == NULL\n");
7999 IXMLDOMElement_Release(element);
8000 hr = IXMLDOMAttribute_get_ownerDocument(attr, NULL);
8001 EXPECT_HR(hr, E_INVALIDARG);
8002 IXMLDOMAttribute_Release(attr);
8003 IXMLDOMNodeList_Release(node_list);
8004
8005 IXMLDOMSchemaCollection_Release(cache);
8006 IXMLDOMDocument_Release(doc1);
8007 IXMLDOMDocument_Release(doc2);
8008 IXMLDOMDocument_Release(doc3);
8009 IXMLDOMDocument2_Release(doc);
8010 IXMLDOMDocument2_Release(doc_owner);
8011 free_bstrs();
8012 }
8013
8014 static void test_setAttributeNode(void)
8015 {
8016 IXMLDOMDocument *doc, *doc2;
8017 IXMLDOMElement *elem, *elem2;
8018 IXMLDOMAttribute *attr, *attr2, *ret_attr;
8019 VARIANT_BOOL b;
8020 HRESULT hr;
8021 VARIANT v;
8022 BSTR str;
8023 ULONG ref1, ref2;
8024
8025 doc = create_document(&IID_IXMLDOMDocument);
8026
8027 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8028 ok( hr == S_OK, "loadXML failed\n");
8029 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8030
8031 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8032 ok( hr == S_OK, "got 0x%08x\n", hr);
8033
8034 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8035 ok( hr == S_OK, "got 0x%08x\n", hr);
8036 ok( elem2 != elem, "got same instance\n");
8037
8038 ret_attr = (void*)0xdeadbeef;
8039 hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8040 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8041 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8042
8043 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8044 ok( hr == S_OK, "got 0x%08x\n", hr);
8045
8046 ref1 = IXMLDOMElement_AddRef(elem);
8047 IXMLDOMElement_Release(elem);
8048
8049 ret_attr = (void*)0xdeadbeef;
8050 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8051 ok( hr == S_OK, "got 0x%08x\n", hr);
8052 ok( ret_attr == NULL, "got %p\n", ret_attr);
8053
8054 /* no reference added */
8055 ref2 = IXMLDOMElement_AddRef(elem);
8056 IXMLDOMElement_Release(elem);
8057 ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8058
8059 EXPECT_CHILDREN(elem);
8060 EXPECT_CHILDREN(elem2);
8061
8062 IXMLDOMElement_Release(elem2);
8063
8064 attr2 = NULL;
8065 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8066 ok( hr == S_OK, "got 0x%08x\n", hr);
8067 ok( attr2 != attr, "got same instance %p\n", attr2);
8068 IXMLDOMAttribute_Release(attr2);
8069
8070 /* try to add it another time */
8071 ret_attr = (void*)0xdeadbeef;
8072 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8073 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8074 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8075
8076 IXMLDOMElement_Release(elem);
8077
8078 /* initially used element is released, attribute still 'has' a container */
8079 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8080 ok( hr == S_OK, "got 0x%08x\n", hr);
8081 ret_attr = (void*)0xdeadbeef;
8082 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8083 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8084 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8085 IXMLDOMElement_Release(elem);
8086
8087 /* add attribute already attached to another document */
8088 doc2 = create_document(&IID_IXMLDOMDocument);
8089
8090 hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8091 ok( hr == S_OK, "loadXML failed\n");
8092 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8093
8094 hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8095 ok( hr == S_OK, "got 0x%08x\n", hr);
8096 hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8097 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8098 IXMLDOMElement_Release(elem);
8099
8100 IXMLDOMAttribute_Release(attr);
8101
8102 /* create element, add attribute, see if it's copied or linked */
8103 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8104 ok( hr == S_OK, "got 0x%08x\n", hr);
8105
8106 attr = NULL;
8107 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8108 ok(hr == S_OK, "got 0x%08x\n", hr);
8109 ok(attr != NULL, "got %p\n", attr);
8110
8111 ref1 = IXMLDOMAttribute_AddRef(attr);
8112 IXMLDOMAttribute_Release(attr);
8113
8114 V_VT(&v) = VT_BSTR;
8115 V_BSTR(&v) = _bstr_("attrvalue1");
8116 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8117 ok( hr == S_OK, "got 0x%08x\n", hr);
8118
8119 str = NULL;
8120 hr = IXMLDOMAttribute_get_xml(attr, &str);
8121 ok( hr == S_OK, "got 0x%08x\n", hr);
8122 ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8123 "got %s\n", wine_dbgstr_w(str));
8124 SysFreeString(str);
8125
8126 ret_attr = (void*)0xdeadbeef;
8127 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8128 ok(hr == S_OK, "got 0x%08x\n", hr);
8129 ok(ret_attr == NULL, "got %p\n", ret_attr);
8130
8131 /* attribute reference increased */
8132 ref2 = IXMLDOMAttribute_AddRef(attr);
8133 IXMLDOMAttribute_Release(attr);
8134 ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8135
8136 hr = IXMLDOMElement_get_xml(elem, &str);
8137 ok( hr == S_OK, "got 0x%08x\n", hr);
8138 ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8139 "got %s\n", wine_dbgstr_w(str));
8140 SysFreeString(str);
8141
8142 V_VT(&v) = VT_BSTR;
8143 V_BSTR(&v) = _bstr_("attrvalue2");
8144 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8145 ok( hr == S_OK, "got 0x%08x\n", hr);
8146
8147 hr = IXMLDOMElement_get_xml(elem, &str);
8148 ok( hr == S_OK, "got 0x%08x\n", hr);
8149 todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8150 "got %s\n", wine_dbgstr_w(str));
8151 SysFreeString(str);
8152
8153 IXMLDOMElement_Release(elem);
8154 IXMLDOMAttribute_Release(attr);
8155 IXMLDOMDocument_Release(doc2);
8156 IXMLDOMDocument_Release(doc);
8157 free_bstrs();
8158 }
8159
8160 static void test_createNode(void)
8161 {
8162 IXMLDOMDocument *doc;
8163 IXMLDOMElement *elem;
8164 IXMLDOMNode *node;
8165 VARIANT v, var;
8166 BSTR prefix, str;
8167 HRESULT hr;
8168 ULONG ref;
8169
8170 doc = create_document(&IID_IXMLDOMDocument);
8171
8172 EXPECT_REF(doc, 1);
8173
8174 /* reference count tests */
8175 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8176 ok( hr == S_OK, "got 0x%08x\n", hr);
8177
8178 /* initial reference is 2 */
8179 todo_wine {
8180 EXPECT_REF(elem, 2);
8181 ref = IXMLDOMElement_Release(elem);
8182 ok(ref == 1, "got %d\n", ref);
8183 /* it's released already, attempt to release now will crash it */
8184 }
8185
8186 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8187 ok( hr == S_OK, "got 0x%08x\n", hr);
8188 todo_wine EXPECT_REF(elem, 2);
8189 IXMLDOMDocument_Release(doc);
8190 todo_wine EXPECT_REF(elem, 2);
8191 IXMLDOMElement_Release(elem);
8192
8193 doc = create_document(&IID_IXMLDOMDocument);
8194
8195 /* NODE_ELEMENT nodes */
8196 /* 1. specified namespace */
8197 V_VT(&v) = VT_I4;
8198 V_I4(&v) = NODE_ELEMENT;
8199
8200 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8201 ok( hr == S_OK, "got 0x%08x\n", hr);
8202 prefix = NULL;
8203 hr = IXMLDOMNode_get_prefix(node, &prefix);
8204 ok( hr == S_OK, "got 0x%08x\n", hr);
8205 ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8206 SysFreeString(prefix);
8207 IXMLDOMNode_Release(node);
8208
8209 /* 2. default namespace */
8210 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8211 ok( hr == S_OK, "got 0x%08x\n", hr);
8212 prefix = (void*)0xdeadbeef;
8213 hr = IXMLDOMNode_get_prefix(node, &prefix);
8214 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8215 ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8216 /* check dump */
8217 hr = IXMLDOMNode_get_xml(node, &str);
8218 ok( hr == S_OK, "got 0x%08x\n", hr);
8219 ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8220 "got %s\n", wine_dbgstr_w(str));
8221 SysFreeString(str);
8222
8223 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8224 ok( hr == S_OK, "got 0x%08x\n", hr);
8225
8226 V_VT(&var) = VT_BSTR;
8227 hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8228 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8229 ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8230
8231 str = NULL;
8232 hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8233 ok( hr == S_OK, "got 0x%08x\n", hr);
8234 ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8235 SysFreeString(str);
8236
8237 IXMLDOMElement_Release(elem);
8238 IXMLDOMNode_Release(node);
8239
8240 IXMLDOMDocument_Release(doc);
8241 free_bstrs();
8242 }
8243
8244 static const char get_prefix_doc[] =
8245 "<?xml version=\"1.0\" ?>"
8246 "<a xmlns:ns1=\"ns1 href\" />";
8247
8248 static void test_get_prefix(void)
8249 {
8250 IXMLDOMDocumentFragment *fragment;
8251 IXMLDOMCDATASection *cdata;
8252 IXMLDOMElement *element;
8253 IXMLDOMComment *comment;
8254 IXMLDOMDocument *doc;
8255 VARIANT_BOOL b;
8256 HRESULT hr;
8257 BSTR str;
8258
8259 doc = create_document(&IID_IXMLDOMDocument);
8260
8261 /* nodes that can't support prefix */
8262 /* 1. document */
8263 str = (void*)0xdeadbeef;
8264 hr = IXMLDOMDocument_get_prefix(doc, &str);
8265 EXPECT_HR(hr, S_FALSE);
8266 ok(str == NULL, "got %p\n", str);
8267
8268 hr = IXMLDOMDocument_get_prefix(doc, NULL);
8269 EXPECT_HR(hr, E_INVALIDARG);
8270
8271 /* 2. cdata */
8272 hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8273 ok(hr == S_OK, "got %08x\n", hr );
8274
8275 str = (void*)0xdeadbeef;
8276 hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8277 ok(hr == S_FALSE, "got %08x\n", hr);
8278 ok( str == 0, "got %p\n", str);
8279
8280 hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8281 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8282 IXMLDOMCDATASection_Release(cdata);
8283
8284 /* 3. comment */
8285 hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8286 ok(hr == S_OK, "got %08x\n", hr );
8287
8288 str = (void*)0xdeadbeef;
8289 hr = IXMLDOMComment_get_prefix(comment, &str);
8290 ok(hr == S_FALSE, "got %08x\n", hr);
8291 ok( str == 0, "got %p\n", str);
8292
8293 hr = IXMLDOMComment_get_prefix(comment, NULL);
8294 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8295 IXMLDOMComment_Release(comment);
8296
8297 /* 4. fragment */
8298 hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8299 ok(hr == S_OK, "got %08x\n", hr );
8300
8301 str = (void*)0xdeadbeef;
8302 hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8303 ok(hr == S_FALSE, "got %08x\n", hr);
8304 ok( str == 0, "got %p\n", str);
8305
8306 hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8307 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8308 IXMLDOMDocumentFragment_Release(fragment);
8309
8310 /* no prefix */
8311 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8312 ok( hr == S_OK, "got 0x%08x\n", hr);
8313
8314 hr = IXMLDOMElement_get_prefix(element, NULL);
8315 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8316
8317 str = (void*)0xdeadbeef;
8318 hr = IXMLDOMElement_get_prefix(element, &str);
8319 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8320 ok( str == 0, "got %p\n", str);
8321
8322 IXMLDOMElement_Release(element);
8323
8324 /* with prefix */
8325 hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8326 ok( hr == S_OK, "got 0x%08x\n", hr);
8327
8328 str = (void*)0xdeadbeef;
8329 hr = IXMLDOMElement_get_prefix(element, &str);
8330 ok( hr == S_OK, "got 0x%08x\n", hr);
8331 ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8332 SysFreeString(str);
8333
8334 str = (void*)0xdeadbeef;
8335 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8336 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8337 ok( str == 0, "got %p\n", str);
8338
8339 IXMLDOMElement_Release(element);
8340
8341 hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8342 EXPECT_HR(hr, S_OK);
8343
8344 hr = IXMLDOMDocument_get_documentElement(doc, &element);
8345 EXPECT_HR(hr, S_OK);
8346
8347 str = (void*)0xdeadbeef;
8348 hr = IXMLDOMElement_get_prefix(element, &str);
8349 EXPECT_HR(hr, S_FALSE);
8350 ok(str == NULL, "got %p\n", str);
8351
8352 str = (void*)0xdeadbeef;
8353 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8354 EXPECT_HR(hr, S_FALSE);
8355 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8356
8357 IXMLDOMDocument_Release(doc);
8358 free_bstrs();
8359 }
8360
8361 static void test_selectSingleNode(void)
8362 {
8363 IXMLDOMDocument *doc;
8364 IXMLDOMNodeList *list;
8365 IXMLDOMNode *node;
8366 VARIANT_BOOL b;
8367 HRESULT hr;
8368 LONG len;
8369
8370 doc = create_document(&IID_IXMLDOMDocument);
8371
8372 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8373 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8374
8375 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8376 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8377
8378 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8379 ok( hr == S_OK, "loadXML failed\n");
8380 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8381
8382 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8383 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8384
8385 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8386 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8387
8388 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8389 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8390
8391 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8392 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8393
8394 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8395 ok(hr == S_OK, "got 0x%08x\n", hr);
8396 IXMLDOMNode_Release(node);
8397
8398 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8399 ok(hr == S_OK, "got 0x%08x\n", hr);
8400 IXMLDOMNodeList_Release(list);
8401
8402 list = (void*)0xdeadbeef;
8403 hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8404 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8405 ok(list == (void*)0xdeadbeef, "got %p\n", list);
8406
8407 node = (void*)0xdeadbeef;
8408 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8409 ok(hr == S_FALSE, "got 0x%08x\n", hr);
8410 ok(node == 0, "got %p\n", node);
8411
8412 list = (void*)0xdeadbeef;
8413 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8414 ok(hr == S_OK, "got 0x%08x\n", hr);
8415 len = 1;
8416 hr = IXMLDOMNodeList_get_length(list, &len);
8417 ok(hr == S_OK, "got 0x%08x\n", hr);
8418 ok(len == 0, "got %d\n", len);
8419 IXMLDOMNodeList_Release(list);
8420
8421 IXMLDOMDocument_Release(doc);
8422 free_bstrs();
8423 }
8424
8425 static void test_events(void)
8426 {
8427 IConnectionPointContainer *conn;
8428 IConnectionPoint *point;
8429 IXMLDOMDocument *doc;
8430 HRESULT hr;
8431 VARIANT v;
8432 IDispatch *event;
8433
8434 doc = create_document(&IID_IXMLDOMDocument);
8435
8436 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8437 ok(hr == S_OK, "got 0x%08x\n", hr);
8438
8439 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8440 ok(hr == S_OK, "got 0x%08x\n", hr);
8441 IConnectionPoint_Release(point);
8442 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8443 ok(hr == S_OK, "got 0x%08x\n", hr);
8444 IConnectionPoint_Release(point);
8445 hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8446 ok(hr == S_OK, "got 0x%08x\n", hr);
8447 IConnectionPoint_Release(point);
8448
8449 IConnectionPointContainer_Release(conn);
8450
8451 /* ready state callback */
8452 VariantInit(&v);
8453 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8454 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8455
8456 event = create_dispevent();
8457 V_VT(&v) = VT_UNKNOWN;
8458 V_UNKNOWN(&v) = (IUnknown*)event;
8459
8460 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8461 ok(hr == S_OK, "got 0x%08x\n", hr);
8462 EXPECT_REF(event, 2);
8463
8464 V_VT(&v) = VT_DISPATCH;
8465 V_DISPATCH(&v) = event;
8466
8467 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8468 ok(hr == S_OK, "got 0x%08x\n", hr);
8469 EXPECT_REF(event, 2);
8470
8471 /* VT_NULL doesn't reset event handler */
8472 V_VT(&v) = VT_NULL;
8473 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8474 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8475 EXPECT_REF(event, 2);
8476
8477 V_VT(&v) = VT_DISPATCH;
8478 V_DISPATCH(&v) = NULL;
8479
8480 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8481 ok(hr == S_OK, "got 0x%08x\n", hr);
8482 EXPECT_REF(event, 1);
8483
8484 V_VT(&v) = VT_UNKNOWN;
8485 V_DISPATCH(&v) = NULL;
8486 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8487 ok(hr == S_OK, "got 0x%08x\n", hr);
8488
8489 IDispatch_Release(event);
8490
8491 IXMLDOMDocument_Release(doc);
8492 }
8493
8494 static void test_createProcessingInstruction(void)
8495 {
8496 static const WCHAR bodyW[] = {'t','e','s','t',0};
8497 IXMLDOMProcessingInstruction *pi;
8498 IXMLDOMDocument *doc;
8499 WCHAR buff[10];
8500 HRESULT hr;
8501
8502 doc = create_document(&IID_IXMLDOMDocument);
8503
8504 /* test for BSTR handling, pass broken BSTR */
8505 memcpy(&buff[2], bodyW, sizeof(bodyW));
8506 /* just a big length */
8507 *(DWORD*)buff = 0xf0f0;
8508 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
8509 ok(hr == S_OK, "got 0x%08x\n", hr);
8510
8511 IXMLDOMProcessingInstruction_Release(pi);
8512 IXMLDOMDocument_Release(doc);
8513 }
8514
8515 static void test_put_nodeTypedValue(void)
8516 {
8517 static const BYTE binhexdata[16] =
8518 {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
8519 IXMLDOMDocument *doc;
8520 IXMLDOMElement *elem;
8521 VARIANT type, value;
8522 LONG ubound, lbound;
8523 IXMLDOMNode *node;
8524 SAFEARRAY *array;
8525 HRESULT hr;
8526 BYTE *ptr;
8527 BSTR str;
8528
8529 doc = create_document(&IID_IXMLDOMDocument);
8530
8531 hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
8532 EXPECT_HR(hr, S_OK);
8533
8534 V_VT(&type) = VT_EMPTY;
8535 hr = IXMLDOMElement_get_dataType(elem, &type);
8536 EXPECT_HR(hr, S_FALSE);
8537 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8538
8539 /* set typed value for untyped node */
8540 V_VT(&type) = VT_I1;
8541 V_I1(&type) = 1;
8542 hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
8543 EXPECT_HR(hr, S_OK);
8544
8545 V_VT(&type) = VT_EMPTY;
8546 hr = IXMLDOMElement_get_dataType(elem, &type);
8547 EXPECT_HR(hr, S_FALSE);
8548 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8549
8550 /* no type info stored */
8551 V_VT(&type) = VT_EMPTY;
8552 hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
8553 EXPECT_HR(hr, S_OK);
8554 ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
8555 ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
8556 "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
8557 VariantClear(&type);
8558
8559 hr = IXMLDOMElement_get_firstChild(elem, &node);
8560 EXPECT_HR(hr, S_OK);
8561 hr = IXMLDOMElement_removeChild(elem, node, NULL);
8562 EXPECT_HR(hr, S_OK);
8563 IXMLDOMNode_Release(node);
8564
8565 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)elem, NULL);
8566 EXPECT_HR(hr, S_OK);
8567
8568 /* bin.base64 */
8569 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.base64"));
8570 EXPECT_HR(hr, S_OK);
8571
8572 V_VT(&value) = VT_BSTR;
8573 V_BSTR(&value) = _bstr_("ABCD");
8574 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8575 EXPECT_HR(hr, S_OK);
8576
8577 V_VT(&value) = VT_EMPTY;
8578 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8579 EXPECT_HR(hr, S_OK);
8580 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8581 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8582 ubound = 0;
8583 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8584 EXPECT_HR(hr, S_OK);
8585 ok(ubound == 2, "got %d\n", ubound);
8586 lbound = 0;
8587 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8588 EXPECT_HR(hr, S_OK);
8589 ok(lbound == 0, "got %d\n", lbound);
8590 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8591 EXPECT_HR(hr, S_OK);
8592 ok(ptr[0] == 0, "got %x\n", ptr[0]);
8593 ok(ptr[1] == 0x10, "got %x\n", ptr[1]);
8594 ok(ptr[2] == 0x83, "got %x\n", ptr[2]);
8595 SafeArrayUnaccessData(V_ARRAY(&value));
8596 VariantClear(&value);
8597
8598 /* when set as VT_BSTR it's stored as is */
8599 hr = IXMLDOMElement_get_firstChild(elem, &node);
8600 EXPECT_HR(hr, S_OK);
8601 hr = IXMLDOMNode_get_text(node, &str);
8602 EXPECT_HR(hr, S_OK);
8603 ok(!lstrcmpW(str, _bstr_("ABCD")), "%s\n", wine_dbgstr_w(str));
8604 IXMLDOMNode_Release(node);
8605 SysFreeString(str);
8606
8607 array = SafeArrayCreateVector(VT_UI1, 0, 7);
8608 hr = SafeArrayAccessData(array, (void*)&ptr);
8609 EXPECT_HR(hr, S_OK);
8610 memcpy(ptr, "dGVzdA=", strlen("dGVzdA="));
8611 SafeArrayUnaccessData(array);
8612
8613 V_VT(&value) = VT_UI1|VT_ARRAY;
8614 V_ARRAY(&value) = array;
8615 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8616 EXPECT_HR(hr, S_OK);
8617
8618 V_VT(&value) = VT_EMPTY;
8619 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8620 EXPECT_HR(hr, S_OK);
8621 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8622 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8623 ubound = 0;
8624 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8625 EXPECT_HR(hr, S_OK);
8626 ok(ubound == 6, "got %d\n", ubound);
8627 lbound = 0;
8628 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8629 EXPECT_HR(hr, S_OK);
8630 ok(lbound == 0, "got %d\n", lbound);
8631 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8632 EXPECT_HR(hr, S_OK);
8633 ok(!memcmp(ptr, "dGVzdA=", strlen("dGVzdA=")), "got wrong data, %s\n", ptr);
8634 SafeArrayUnaccessData(V_ARRAY(&value));
8635 VariantClear(&value);
8636
8637 /* if set with VT_UI1|VT_ARRAY it's encoded */
8638 hr = IXMLDOMElement_get_firstChild(elem, &node);
8639 EXPECT_HR(hr, S_OK);
8640 hr = IXMLDOMNode_get_text(node, &str);
8641 EXPECT_HR(hr, S_OK);
8642 ok(!lstrcmpW(str, _bstr_("ZEdWemRBPQ==")), "%s\n", wine_dbgstr_w(str));
8643 IXMLDOMNode_Release(node);
8644 SafeArrayDestroyData(array);
8645 SysFreeString(str);
8646
8647 /* bin.hex */
8648 V_VT(&value) = VT_BSTR;
8649 V_BSTR(&value) = _bstr_("");
8650 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8651 EXPECT_HR(hr, S_OK);
8652
8653 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.hex"));
8654 EXPECT_HR(hr, S_OK);
8655
8656 array = SafeArrayCreateVector(VT_UI1, 0, 16);
8657 hr = SafeArrayAccessData(array, (void*)&ptr);
8658 EXPECT_HR(hr, S_OK);
8659 memcpy(ptr, binhexdata, sizeof(binhexdata));
8660 SafeArrayUnaccessData(array);
8661
8662 V_VT(&value) = VT_UI1|VT_ARRAY;
8663 V_ARRAY(&value) = array;
8664 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8665 EXPECT_HR(hr, S_OK);
8666
8667 V_VT(&value) = VT_EMPTY;
8668 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8669 EXPECT_HR(hr, S_OK);
8670 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8671 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8672 ubound = 0;
8673 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8674 EXPECT_HR(hr, S_OK);
8675 ok(ubound == 15, "got %d\n", ubound);
8676 lbound = 0;
8677 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8678 EXPECT_HR(hr, S_OK);
8679 ok(lbound == 0, "got %d\n", lbound);
8680 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8681 EXPECT_HR(hr, S_OK);
8682 ok(!memcmp(ptr, binhexdata, sizeof(binhexdata)), "got wrong data\n");
8683 SafeArrayUnaccessData(V_ARRAY(&value));
8684 VariantClear(&value);
8685
8686 /* if set with VT_UI1|VT_ARRAY it's encoded */
8687 hr = IXMLDOMElement_get_firstChild(elem, &node);
8688 EXPECT_HR(hr, S_OK);
8689 hr = IXMLDOMNode_get_text(node, &str);
8690 EXPECT_HR(hr, S_OK);
8691 ok(!lstrcmpW(str, _bstr_("000102030405060708090a0b0c0d0e0f")), "%s\n", wine_dbgstr_w(str));
8692 IXMLDOMNode_Release(node);
8693 SafeArrayDestroyData(array);
8694 SysFreeString(str);
8695
8696 IXMLDOMElement_Release(elem);
8697 IXMLDOMDocument_Release(doc);
8698 free_bstrs();
8699 }
8700
8701 static void test_get_xml(void)
8702 {
8703 static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
8704 static const char attrA[] = "attr=\"&quot;a &amp; b&quot;\"";
8705 static const char attr2A[] = "\"a & b\"";
8706 static const char attr3A[] = "attr=\"&amp;quot;a\"";
8707 static const char attr4A[] = "&quot;a";
8708 static const char fooA[] = "<foo/>";
8709 IXMLDOMProcessingInstruction *pi;
8710 IXMLDOMNode *first;
8711 IXMLDOMElement *elem = NULL;
8712 IXMLDOMAttribute *attr;
8713 IXMLDOMDocument *doc;
8714 VARIANT_BOOL b;
8715 VARIANT v;
8716 BSTR xml;
8717 HRESULT hr;
8718
8719 doc = create_document(&IID_IXMLDOMDocument);
8720
8721 b = VARIANT_TRUE;
8722 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8723 ok(hr == S_OK, "got 0x%08x\n", hr);
8724 ok( b == VARIANT_TRUE, "got %d\n", b);
8725
8726 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
8727 _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
8728 ok(hr == S_OK, "got 0x%08x\n", hr);
8729
8730 hr = IXMLDOMDocument_get_firstChild(doc, &first);
8731 ok(hr == S_OK, "got 0x%08x\n", hr);
8732
8733 V_UNKNOWN(&v) = (IUnknown*)first;
8734 V_VT(&v) = VT_UNKNOWN;
8735
8736 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
8737 ok(hr == S_OK, "got 0x%08x\n", hr);
8738
8739 IXMLDOMProcessingInstruction_Release(pi);
8740 IXMLDOMNode_Release(first);
8741
8742 hr = IXMLDOMDocument_get_xml(doc, &xml);
8743 ok(hr == S_OK, "got 0x%08x\n", hr);
8744
8745 ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
8746 "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
8747 SysFreeString(xml);
8748
8749 IXMLDOMDocument_Release(doc);
8750
8751 doc = create_document(&IID_IXMLDOMDocument);
8752
8753 hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
8754 ok(hr == S_OK, "got 0x%08x\n", hr);
8755
8756 hr = IXMLDOMDocument_putref_documentElement(doc, elem);
8757 ok(hr == S_OK, "got 0x%08x\n", hr);
8758
8759 hr = IXMLDOMDocument_get_xml(doc, &xml);
8760 ok(hr == S_OK, "got 0x%08x\n", hr);
8761
8762 ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
8763 "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
8764 SysFreeString(xml);
8765
8766 IXMLDOMElement_Release(elem);
8767
8768 /* attribute node */
8769 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8770 ok(hr == S_OK, "got 0x%08x\n", hr);
8771
8772 V_VT(&v) = VT_BSTR;
8773 V_BSTR(&v) = _bstr_("\"a & b\"");
8774 hr = IXMLDOMAttribute_put_value(attr, v);
8775 ok(hr == S_OK, "got 0x%08x\n", hr);
8776
8777 xml = NULL;
8778 hr = IXMLDOMAttribute_get_xml(attr, &xml);
8779 ok(hr == S_OK, "got 0x%08x\n", hr);
8780 ok(!memcmp(xml, _bstr_(attrA), (sizeof(attrA)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
8781 SysFreeString(xml);
8782
8783 VariantInit(&v);
8784 hr = IXMLDOMAttribute_get_value(attr, &v);
8785 ok(hr == S_OK, "got 0x%08x\n", hr);
8786 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8787 ok(!memcmp(V_BSTR(&v), _bstr_(attr2A), (sizeof(attr2A)-1)*sizeof(WCHAR)),
8788 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8789 VariantClear(&v);
8790
8791 V_VT(&v) = VT_BSTR;
8792 V_BSTR(&v) = _bstr_("&quot;a");
8793 hr = IXMLDOMAttribute_put_value(attr, v);
8794 ok(hr == S_OK, "got 0x%08x\n", hr);
8795
8796 xml = NULL;
8797 hr = IXMLDOMAttribute_get_xml(attr, &xml);
8798 ok(hr == S_OK, "got 0x%08x\n", hr);
8799 ok(!memcmp(xml, _bstr_(attr3A), (sizeof(attr3A)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
8800 SysFreeString(xml);
8801
8802 VariantInit(&v);
8803 hr = IXMLDOMAttribute_get_value(attr, &v);
8804 ok(hr == S_OK, "got 0x%08x\n", hr);
8805 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8806 ok(!memcmp(V_BSTR(&v), _bstr_(attr4A), (sizeof(attr4A)-1)*sizeof(WCHAR)),
8807 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8808 VariantClear(&v);
8809
8810 IXMLDOMAttribute_Release(attr);
8811
8812 IXMLDOMDocument_Release(doc);
8813
8814 free_bstrs();
8815 }
8816
8817 static void test_xsltemplate(void)
8818 {
8819 IXMLDOMDocument *doc, *doc2, *doc3;
8820 IXSLTemplate *template;
8821 IXSLProcessor *processor;
8822 IStream *stream;
8823 VARIANT_BOOL b;
8824 HRESULT hr;
8825 ULONG ref1, ref2;
8826 VARIANT v;
8827 BSTR str;
8828
8829 if (!is_clsid_supported(&CLSID_XSLTemplate, &IID_IXSLTemplate)) return;
8830 template = create_xsltemplate(&IID_IXSLTemplate);
8831
8832 /* works as reset */
8833 hr = IXSLTemplate_putref_stylesheet(template, NULL);
8834 ok(hr == S_OK, "got 0x%08x\n", hr);
8835
8836 doc = create_document(&IID_IXMLDOMDocument);
8837
8838 b = VARIANT_TRUE;
8839 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8840 ok(hr == S_OK, "got 0x%08x\n", hr);
8841 ok( b == VARIANT_TRUE, "got %d\n", b);
8842
8843 /* putref with non-xsl document */
8844 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8845 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8846
8847 b = VARIANT_TRUE;
8848 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8849 ok(hr == S_OK, "got 0x%08x\n", hr);
8850 ok( b == VARIANT_TRUE, "got %d\n", b);
8851
8852 /* not a freethreaded document */
8853 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8854 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8855
8856 IXMLDOMDocument_Release(doc);
8857
8858 if (!is_clsid_supported(&CLSID_FreeThreadedDOMDocument, &IID_IXMLDOMDocument))
8859 {
8860 IXSLTemplate_Release(template);
8861 return;
8862 }
8863
8864 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
8865 ok(hr == S_OK, "got 0x%08x\n", hr);
8866
8867 b = VARIANT_TRUE;
8868 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8869 ok(hr == S_OK, "got 0x%08x\n", hr);
8870 ok( b == VARIANT_TRUE, "got %d\n", b);
8871
8872 /* freethreaded document */
8873 ref1 = IXMLDOMDocument_AddRef(doc);
8874 IXMLDOMDocument_Release(doc);
8875 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8876 ok(hr == S_OK, "got 0x%08x\n", hr);
8877 ref2 = IXMLDOMDocument_AddRef(doc);
8878 IXMLDOMDocument_Release(doc);
8879 ok(ref2 > ref1, "got %d\n", ref2);
8880
8881 /* processor */
8882 hr = IXSLTemplate_createProcessor(template, NULL);
8883 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8884
8885 EXPECT_REF(template, 1);
8886 hr = IXSLTemplate_createProcessor(template, &processor);
8887 ok(hr == S_OK, "got 0x%08x\n", hr);
8888 EXPECT_REF(template, 2);
8889
8890 /* input no set yet */
8891 V_VT(&v) = VT_BSTR;
8892 V_BSTR(&v) = NULL;
8893 hr = IXSLProcessor_get_input(processor, &v);
8894 todo_wine {
8895 ok(hr == S_OK, "got 0x%08x\n", hr);
8896 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
8897 }
8898
8899 hr = IXSLProcessor_get_output(processor, NULL);
8900 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8901
8902 /* reset before it was set */
8903 V_VT(&v) = VT_EMPTY;
8904 hr = IXSLProcessor_put_output(processor, v);
8905 ok(hr == S_OK, "got 0x%08x\n", hr);
8906
8907 V_VT(&v) = VT_UNKNOWN;
8908 V_UNKNOWN(&v) = NULL;
8909 hr = IXSLProcessor_put_output(processor, v);
8910 ok(hr == S_OK, "got 0x%08x\n", hr);
8911
8912 V_VT(&v) = VT_UNKNOWN;
8913 V_DISPATCH(&v) = NULL;
8914 hr = IXSLProcessor_put_output(processor, v);
8915 ok(hr == S_OK, "got 0x%08x\n", hr);
8916
8917 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
8918 ok(hr == S_OK, "got 0x%08x\n", hr);
8919 EXPECT_REF(stream, 1);
8920
8921 V_VT(&v) = VT_UNKNOWN;
8922 V_UNKNOWN(&v) = (IUnknown*)stream;
8923 hr = IXSLProcessor_put_output(processor, v);
8924 ok(hr == S_OK, "got 0x%08x\n", hr);
8925
8926 /* it seems processor grabs 2 references */
8927 todo_wine EXPECT_REF(stream, 3);
8928
8929 V_VT(&v) = VT_EMPTY;
8930 hr = IXSLProcessor_get_output(processor, &v);
8931 ok(hr == S_OK, "got 0x%08x\n", hr);
8932 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
8933 ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
8934
8935 todo_wine EXPECT_REF(stream, 4);
8936 VariantClear(&v);
8937
8938 hr = IXSLProcessor_transform(processor, NULL);
8939 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8940
8941 /* reset and check stream refcount */
8942 V_VT(&v) = VT_EMPTY;
8943 hr = IXSLProcessor_put_output(processor, v);
8944 ok(hr == S_OK, "got 0x%08x\n", hr);
8945
8946 EXPECT_REF(stream, 1);
8947
8948 IStream_Release(stream);
8949
8950 /* no output interface set, check output */
8951 doc2 = create_document(&IID_IXMLDOMDocument);
8952
8953 b = VARIANT_FALSE;
8954 hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
8955 ok(hr == S_OK, "got 0x%08x\n", hr);
8956 ok( b == VARIANT_TRUE, "got %d\n", b);
8957
8958 V_VT(&v) = VT_UNKNOWN;
8959 V_UNKNOWN(&v) = (IUnknown*)doc2;
8960 hr = IXSLProcessor_put_input(processor, v);
8961 ok(hr == S_OK, "got 0x%08x\n", hr);
8962
8963 hr = IXSLProcessor_transform(processor, &b);
8964 ok(hr == S_OK, "got 0x%08x\n", hr);
8965
8966 V_VT(&v) = VT_EMPTY;
8967 hr = IXSLProcessor_get_output(processor, &v);
8968 ok(hr == S_OK, "got 0x%08x\n", hr);
8969 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8970 ok(*V_BSTR(&v) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8971 VariantClear(&v);
8972
8973 /* transform to document */
8974 b = VARIANT_FALSE;
8975 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformXML), &b);
8976 ok(hr == S_OK, "got 0x%08x\n", hr);
8977 ok(b == VARIANT_TRUE, "got %d\n", b);
8978
8979 V_VT(&v) = VT_UNKNOWN;
8980 V_UNKNOWN(&v) = (IUnknown*)doc2;
8981 hr = IXSLProcessor_put_input(processor, v);
8982 ok(hr == S_OK, "got 0x%08x\n", hr);
8983
8984 doc3 = create_document(&IID_IXMLDOMDocument);
8985 V_VT(&v) = VT_UNKNOWN;
8986 V_UNKNOWN(&v) = (IUnknown *)doc3;
8987 hr = IXSLProcessor_put_output(processor, v);
8988 ok(hr == S_OK, "got 0x%08x\n", hr);
8989
8990 hr = IXMLDOMDocument_get_xml(doc3, &str);
8991 ok(hr == S_OK, "got 0x%08x\n", hr);
8992 ok(!*str, "Expected empty document\n");
8993 SysFreeString(str);
8994
8995 hr = IXSLProcessor_transform(processor, &b);
8996 ok(hr == S_OK, "got 0x%08x\n", hr);
8997
8998 V_VT(&v) = VT_EMPTY;
8999 hr = IXSLProcessor_get_output(processor, &v);
9000 ok(hr == S_OK, "got 0x%08x\n", hr);
9001 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9002 VariantClear(&v);
9003
9004 hr = IXMLDOMDocument_get_xml(doc3, &str);
9005 ok(hr == S_OK, "got 0x%08x\n", hr);
9006 ok(!!*str, "Expected document\n");
9007 SysFreeString(str);
9008
9009 /* transform to IResponse */
9010 V_VT(&v) = VT_EMPTY;
9011 hr = IXSLProcessor_put_output(processor, v);
9012 ok(hr == S_OK, "got 0x%08x\n", hr);
9013
9014 V_VT(&v) = VT_UNKNOWN;
9015 V_UNKNOWN(&v) = (IUnknown *)&testresponse;
9016 hr = IXSLProcessor_put_output(processor, v);
9017 ok(hr == S_OK, "got 0x%08x\n", hr);
9018
9019 b = VARIANT_FALSE;
9020 hr = IXSLProcessor_transform(processor, &b);
9021 ok(hr == S_OK, "got 0x%08x\n", hr);
9022 ok(b == VARIANT_TRUE, "got %x\n", b);
9023
9024 IXSLProcessor_Release(processor);
9025 IXMLDOMDocument_Release(doc2);
9026 IXMLDOMDocument_Release(doc3);
9027
9028 /* drop reference */
9029 hr = IXSLTemplate_putref_stylesheet(template, NULL);
9030 ok(hr == S_OK, "got 0x%08x\n", hr);
9031 ref2 = IXMLDOMDocument_AddRef(doc);
9032 IXMLDOMDocument_Release(doc);
9033 ok(ref2 == ref1, "got %d\n", ref2);
9034
9035 IXMLDOMDocument_Release(doc);
9036 IXSLTemplate_Release(template);
9037 free_bstrs();
9038 }
9039
9040 static void test_insertBefore(void)
9041 {
9042 IXMLDOMDocument *doc, *doc2, *doc3;
9043 IXMLDOMAttribute *attr;
9044 IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9045 IXMLDOMNode *node, *newnode, *cdata;
9046 HRESULT hr;
9047 VARIANT v;
9048 BSTR p;
9049
9050 doc = create_document(&IID_IXMLDOMDocument);
9051 doc3 = create_document(&IID_IXMLDOMDocument);
9052
9053 /* document to document */
9054 V_VT(&v) = VT_NULL;
9055 node = (void*)0xdeadbeef;
9056 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc3, v, &node);
9057 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9058 ok(node == NULL, "got %p\n", node);
9059
9060 /* document to itself */
9061 V_VT(&v) = VT_NULL;
9062 node = (void*)0xdeadbeef;
9063 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc, v, &node);
9064 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9065 ok(node == NULL, "got %p\n", node);
9066
9067 /* insertBefore behaviour for attribute node */
9068 V_VT(&v) = VT_I4;
9069 V_I4(&v) = NODE_ATTRIBUTE;
9070
9071 attr = NULL;
9072 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9073 ok(hr == S_OK, "got 0x%08x\n", hr);
9074 ok(attr != NULL, "got %p\n", attr);
9075
9076 /* attribute to document */
9077 V_VT(&v) = VT_NULL;
9078 node = (void*)0xdeadbeef;
9079 hr = IXMLDOMDocument_insertBefore(doc3, (IXMLDOMNode*)attr, v, &node);
9080 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9081 ok(node == NULL, "got %p\n", node);
9082
9083 /* cdata to document */
9084 V_VT(&v) = VT_I4;
9085 V_I4(&v) = NODE_CDATA_SECTION;
9086
9087 cdata = NULL;
9088 hr = IXMLDOMDocument_createNode(doc3, v, _bstr_("cdata"), NULL, &cdata);
9089 ok(hr == S_OK, "got 0x%08x\n", hr);
9090 ok(cdata != NULL, "got %p\n", cdata);
9091
9092 EXPECT_NO_CHILDREN(cdata);
9093
9094 /* attribute to cdata */
9095 V_VT(&v) = VT_NULL;
9096 node = (void*)0xdeadbeef;
9097 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)attr, v, &node);
9098 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9099 ok(node == NULL, "got %p\n", node);
9100
9101 /* document to cdata */
9102 V_VT(&v) = VT_NULL;
9103 node = (void*)0xdeadbeef;
9104 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)doc, v, &node);
9105 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9106 ok(node == NULL, "got %p\n", node);
9107
9108 V_VT(&v) = VT_NULL;
9109 node = (void*)0xdeadbeef;
9110 hr = IXMLDOMDocument_insertBefore(doc3, cdata, v, &node);
9111 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9112 ok(node == NULL, "got %p\n", node);
9113
9114 IXMLDOMNode_Release(cdata);
9115 IXMLDOMDocument_Release(doc3);
9116
9117 /* attribute to attribute */
9118 V_VT(&v) = VT_I4;
9119 V_I4(&v) = NODE_ATTRIBUTE;
9120 newnode = NULL;
9121 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9122 ok(hr == S_OK, "got 0x%08x\n", hr);
9123 ok(newnode != NULL, "got %p\n", newnode);
9124
9125 V_VT(&v) = VT_NULL;
9126 node = (void*)0xdeadbeef;
9127 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9128 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9129 ok(node == NULL, "got %p\n", node);
9130
9131 V_VT(&v) = VT_UNKNOWN;
9132 V_UNKNOWN(&v) = (IUnknown*)attr;
9133 node = (void*)0xdeadbeef;
9134 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9135 todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9136 ok(node == NULL, "got %p\n", node);
9137 IXMLDOMNode_Release(newnode);
9138
9139 /* cdata to attribute */
9140 V_VT(&v) = VT_I4;
9141 V_I4(&v) = NODE_CDATA_SECTION;
9142 newnode = NULL;
9143 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9144 ok(hr == S_OK, "got 0x%08x\n", hr);
9145 ok(newnode != NULL, "got %p\n", newnode);
9146
9147 V_VT(&v) = VT_NULL;
9148 node = (void*)0xdeadbeef;
9149 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9150 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9151 ok(node == NULL, "got %p\n", node);
9152 IXMLDOMNode_Release(newnode);
9153
9154 /* comment to attribute */
9155 V_VT(&v) = VT_I4;
9156 V_I4(&v) = NODE_COMMENT;
9157 newnode = NULL;
9158 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9159 ok(hr == S_OK, "got 0x%08x\n", hr);
9160 ok(newnode != NULL, "got %p\n", newnode);
9161
9162 V_VT(&v) = VT_NULL;
9163 node = (void*)0xdeadbeef;
9164 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9165 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9166 ok(node == NULL, "got %p\n", node);
9167 IXMLDOMNode_Release(newnode);
9168
9169 /* element to attribute */
9170 V_VT(&v) = VT_I4;
9171 V_I4(&v) = NODE_ELEMENT;
9172 newnode = NULL;
9173 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9174 ok(hr == S_OK, "got 0x%08x\n", hr);
9175 ok(newnode != NULL, "got %p\n", newnode);
9176
9177 V_VT(&v) = VT_NULL;
9178 node = (void*)0xdeadbeef;
9179 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9180 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9181 ok(node == NULL, "got %p\n", node);
9182 IXMLDOMNode_Release(newnode);
9183
9184 /* pi to attribute */
9185 V_VT(&v) = VT_I4;
9186 V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9187 newnode = NULL;
9188 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9189 ok(hr == S_OK, "got 0x%08x\n", hr);
9190 ok(newnode != NULL, "got %p\n", newnode);
9191
9192 V_VT(&v) = VT_NULL;
9193 node = (void*)0xdeadbeef;
9194 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9195 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9196 ok(node == NULL, "got %p\n", node);
9197 IXMLDOMNode_Release(newnode);
9198 IXMLDOMAttribute_Release(attr);
9199
9200 /* insertBefore for elements */
9201 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9202 ok(hr == S_OK, "got 0x%08x\n", hr);
9203
9204 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9205 ok(hr == S_OK, "got 0x%08x\n", hr);
9206
9207 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9208 ok(hr == S_OK, "got 0x%08x\n", hr);
9209
9210 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9211 ok(hr == S_OK, "got 0x%08x\n", hr);
9212
9213 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9214 ok(hr == S_OK, "got 0x%08x\n", hr);
9215
9216 EXPECT_NO_CHILDREN(elem1);
9217 EXPECT_NO_CHILDREN(elem2);
9218 EXPECT_NO_CHILDREN(elem3);
9219
9220 todo_wine EXPECT_REF(elem2, 2);
9221
9222 /* document to element */
9223 V_VT(&v) = VT_DISPATCH;
9224 V_DISPATCH(&v) = NULL;
9225 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)doc, v, NULL);
9226 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9227
9228 V_VT(&v) = VT_DISPATCH;
9229 V_DISPATCH(&v) = NULL;
9230 node = NULL;
9231 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9232 ok(hr == S_OK, "got 0x%08x\n", hr);
9233 ok(node == (void*)elem4, "got %p\n", node);
9234
9235 EXPECT_CHILDREN(elem1);
9236 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9237 EXPECT_HR(hr, S_OK);
9238 IXMLDOMElement_Release(elem4);
9239
9240 EXPECT_NO_CHILDREN(elem1);
9241
9242 V_VT(&v) = VT_NULL;
9243 node = NULL;
9244 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9245 ok(hr == S_OK, "got 0x%08x\n", hr);
9246 ok(node == (void*)elem2, "got %p\n", node);
9247
9248 EXPECT_CHILDREN(elem1);
9249 todo_wine EXPECT_REF(elem2, 3);
9250 IXMLDOMNode_Release(node);
9251
9252 /* again for already linked node */
9253 V_VT(&v) = VT_NULL;
9254 node = NULL;
9255 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9256 ok(hr == S_OK, "got 0x%08x\n", hr);
9257 ok(node == (void*)elem2, "got %p\n", node);
9258
9259 EXPECT_CHILDREN(elem1);
9260
9261 /* increments each time */
9262 todo_wine EXPECT_REF(elem2, 3);
9263 IXMLDOMNode_Release(node);
9264
9265 /* try to add to another element */
9266 V_VT(&v) = VT_NULL;
9267 node = (void*)0xdeadbeef;
9268 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9269 ok(hr == S_OK, "got 0x%08x\n", hr);
9270 ok(node == (void*)elem2, "got %p\n", node);
9271
9272 EXPECT_CHILDREN(elem3);
9273 EXPECT_NO_CHILDREN(elem1);
9274
9275 IXMLDOMNode_Release(node);
9276
9277 /* cross document case - try to add as child to a node created with other doc */
9278 doc2 = create_document(&IID_IXMLDOMDocument);
9279
9280 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9281 ok(hr == S_OK, "got 0x%08x\n", hr);
9282 todo_wine EXPECT_REF(elem4, 2);
9283
9284 /* same name, another instance */
9285 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9286 ok(hr == S_OK, "got 0x%08x\n", hr);
9287 todo_wine EXPECT_REF(elem5, 2);
9288
9289 todo_wine EXPECT_REF(elem3, 2);
9290 V_VT(&v) = VT_NULL;
9291 node = NULL;
9292 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9293 ok(hr == S_OK, "got 0x%08x\n", hr);
9294 ok(node == (void*)elem4, "got %p\n", node);
9295 todo_wine EXPECT_REF(elem4, 3);
9296 todo_wine EXPECT_REF(elem3, 2);
9297 IXMLDOMNode_Release(node);
9298
9299 V_VT(&v) = VT_NULL;
9300 node = NULL;
9301 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9302 ok(hr == S_OK, "got 0x%08x\n", hr);
9303 ok(node == (void*)elem5, "got %p\n", node);
9304 todo_wine EXPECT_REF(elem4, 2);
9305 todo_wine EXPECT_REF(elem5, 3);
9306 IXMLDOMNode_Release(node);
9307
9308 IXMLDOMDocument_Release(doc2);
9309
9310 IXMLDOMElement_Release(elem1);
9311 IXMLDOMElement_Release(elem2);
9312 IXMLDOMElement_Release(elem3);
9313 IXMLDOMElement_Release(elem4);
9314 IXMLDOMElement_Release(elem5);
9315
9316 /* elements with same default namespace */
9317 V_VT(&v) = VT_I4;
9318 V_I4(&v) = NODE_ELEMENT;
9319 elem1 = NULL;
9320 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9321 ok(hr == S_OK, "got 0x%08x\n", hr);
9322 ok(elem1 != NULL, "got %p\n", elem1);
9323
9324 V_VT(&v) = VT_I4;
9325 V_I4(&v) = NODE_ELEMENT;
9326 elem2 = NULL;
9327 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9328 ok(hr == S_OK, "got 0x%08x\n", hr);
9329 ok(elem2 != NULL, "got %p\n", elem2);
9330
9331 /* check contents so far */
9332 p = NULL;
9333 hr = IXMLDOMElement_get_xml(elem1, &p);
9334 ok(hr == S_OK, "got 0x%08x\n", hr);
9335 ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9336 SysFreeString(p);
9337
9338 p = NULL;
9339 hr = IXMLDOMElement_get_xml(elem2, &p);
9340 ok(hr == S_OK, "got 0x%08x\n", hr);
9341 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9342 SysFreeString(p);
9343
9344 V_VT(&v) = VT_NULL;
9345 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9346 ok(hr == S_OK, "got 0x%08x\n", hr);
9347
9348 /* get_xml depends on context, for top node it omits child namespace attribute,
9349 but at child level it's still returned */
9350 p = NULL;
9351 hr = IXMLDOMElement_get_xml(elem1, &p);
9352 ok(hr == S_OK, "got 0x%08x\n", hr);
9353 todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9354 "got %s\n", wine_dbgstr_w(p));
9355 SysFreeString(p);
9356
9357 p = NULL;
9358 hr = IXMLDOMElement_get_xml(elem2, &p);
9359 ok(hr == S_OK, "got 0x%08x\n", hr);
9360 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9361 SysFreeString(p);
9362
9363 IXMLDOMElement_Release(elem1);
9364 IXMLDOMElement_Release(elem2);
9365
9366 /* child without default namespace added to node with default namespace */
9367 V_VT(&v) = VT_I4;
9368 V_I4(&v) = NODE_ELEMENT;
9369 elem1 = NULL;
9370 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9371 ok(hr == S_OK, "got 0x%08x\n", hr);
9372 ok(elem1 != NULL, "got %p\n", elem1);
9373
9374 V_VT(&v) = VT_I4;
9375 V_I4(&v) = NODE_ELEMENT;
9376 elem2 = NULL;
9377 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9378 ok(hr == S_OK, "got 0x%08x\n", hr);
9379 ok(elem2 != NULL, "got %p\n", elem2);
9380
9381 EXPECT_REF(elem2, 1);
9382 V_VT(&v) = VT_NULL;
9383 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9384 ok(hr == S_OK, "got 0x%08x\n", hr);
9385 EXPECT_REF(elem2, 1);
9386
9387 p = NULL;
9388 hr = IXMLDOMElement_get_xml(elem2, &p);
9389 ok(hr == S_OK, "got 0x%08x\n", hr);
9390 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9391 SysFreeString(p);
9392
9393 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9394 ok(hr == S_OK, "got 0x%08x\n", hr);
9395
9396 p = NULL;
9397 hr = IXMLDOMElement_get_xml(elem2, &p);
9398 ok(hr == S_OK, "got 0x%08x\n", hr);
9399 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9400 SysFreeString(p);
9401
9402 IXMLDOMElement_Release(elem1);
9403 IXMLDOMElement_Release(elem2);
9404 IXMLDOMDocument_Release(doc);
9405 }
9406
9407 static void test_appendChild(void)
9408 {
9409 IXMLDOMDocument *doc, *doc2;
9410 IXMLDOMElement *elem, *elem2;
9411 HRESULT hr;
9412
9413 doc = create_document(&IID_IXMLDOMDocument);
9414 doc2 = create_document(&IID_IXMLDOMDocument);
9415
9416 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9417 ok(hr == S_OK, "got 0x%08x\n", hr);
9418
9419 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9420 ok(hr == S_OK, "got 0x%08x\n", hr);
9421
9422 EXPECT_REF(doc, 1);
9423 todo_wine EXPECT_REF(elem, 2);
9424 EXPECT_REF(doc2, 1);
9425 todo_wine EXPECT_REF(elem2, 2);
9426 EXPECT_NO_CHILDREN(doc);
9427 EXPECT_NO_CHILDREN(doc2);
9428
9429 hr = IXMLDOMDocument_appendChild(doc2, NULL, NULL);
9430 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9431
9432 hr = IXMLDOMElement_appendChild(elem, NULL, NULL);
9433 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9434
9435 /* append from another document */
9436 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9437 ok(hr == S_OK, "got 0x%08x\n", hr);
9438
9439 EXPECT_REF(doc, 1);
9440 todo_wine EXPECT_REF(elem, 2);
9441 EXPECT_REF(doc2, 1);
9442 todo_wine EXPECT_REF(elem2, 2);
9443 EXPECT_NO_CHILDREN(doc);
9444 EXPECT_CHILDREN(doc2);
9445
9446 IXMLDOMElement_Release(elem);
9447 IXMLDOMElement_Release(elem2);
9448 IXMLDOMDocument_Release(doc);
9449 IXMLDOMDocument_Release(doc2);
9450 }
9451
9452 static void test_get_doctype(void)
9453 {
9454 static const WCHAR emailW[] = {'e','m','a','i','l',0};
9455 IXMLDOMDocumentType *doctype;
9456 IXMLDOMDocument *doc;
9457 VARIANT_BOOL b;
9458 HRESULT hr;
9459 BSTR s;
9460
9461 doc = create_document(&IID_IXMLDOMDocument);
9462
9463 hr = IXMLDOMDocument_get_doctype(doc, NULL);
9464 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9465
9466 doctype = (void*)0xdeadbeef;
9467 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9468 ok(hr == S_FALSE, "got 0x%08x\n", hr);
9469 ok(doctype == NULL, "got %p\n", doctype);
9470
9471 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szEmailXML), &b);
9472 ok(hr == S_OK, "got 0x%08x\n", hr);
9473 ok(b == VARIANT_TRUE, "failed to load XML string\n");
9474
9475 doctype = NULL;
9476 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9477 ok(hr == S_OK, "got 0x%08x\n", hr);
9478 ok(doctype != NULL, "got %p\n", doctype);
9479
9480 hr = IXMLDOMDocumentType_get_name(doctype, NULL);
9481 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9482
9483 hr = IXMLDOMDocumentType_get_name(doctype, &s);
9484 ok(hr == S_OK, "got 0x%08x\n", hr);
9485 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s));
9486 SysFreeString(s);
9487
9488 hr = IXMLDOMDocumentType_get_nodeName(doctype, &s);
9489 ok(hr == S_OK, "got 0x%08x\n", hr);
9490 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s));
9491 SysFreeString(s);
9492
9493 IXMLDOMDocumentType_Release(doctype);
9494 IXMLDOMDocument_Release(doc);
9495 }
9496
9497 static void test_get_tagName(void)
9498 {
9499 IXMLDOMDocument *doc;
9500 IXMLDOMElement *elem, *elem2;
9501 HRESULT hr;
9502 BSTR str;
9503
9504 doc = create_document(&IID_IXMLDOMDocument);
9505
9506 hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9507 ok(hr == S_OK, "got 0x%08x\n", hr);
9508
9509 hr = IXMLDOMElement_get_tagName(elem, NULL);
9510 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9511
9512 str = NULL;
9513 hr = IXMLDOMElement_get_tagName(elem, &str);
9514 ok(hr == S_OK, "got 0x%08x\n", hr);
9515 ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9516 SysFreeString(str);
9517
9518 hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9519 ok(hr == S_OK, "got 0x%08x\n", hr);
9520
9521 str = NULL;
9522 hr = IXMLDOMElement_get_tagName(elem2, &str);
9523 ok(hr == S_OK, "got 0x%08x\n", hr);
9524 ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9525 SysFreeString(str);
9526
9527 IXMLDOMElement_Release(elem);
9528 IXMLDOMElement_Release(elem2);
9529 IXMLDOMDocument_Release(doc);
9530 free_bstrs();
9531 }
9532
9533 typedef struct {
9534 DOMNodeType type;
9535 const char *name;
9536 VARTYPE vt;
9537 HRESULT hr;
9538 } node_type_t;
9539
9540 static const node_type_t get_datatype[] = {
9541 { NODE_ELEMENT, "element", VT_NULL, S_FALSE },
9542 { NODE_ATTRIBUTE, "attr", VT_NULL, S_FALSE },
9543 { NODE_TEXT, "text", VT_NULL, S_FALSE },
9544 { NODE_CDATA_SECTION , "cdata", VT_NULL, S_FALSE },
9545 { NODE_ENTITY_REFERENCE, "entityref", VT_NULL, S_FALSE },
9546 { NODE_PROCESSING_INSTRUCTION, "pi", VT_NULL, S_FALSE },
9547 { NODE_COMMENT, "comment", VT_NULL, S_FALSE },
9548 { NODE_DOCUMENT_FRAGMENT, "docfrag", VT_NULL, S_FALSE },
9549 { 0 }
9550 };
9551
9552 static void test_get_dataType(void)
9553 {
9554 const node_type_t *entry = get_datatype;
9555 IXMLDOMDocument *doc;
9556
9557 doc = create_document(&IID_IXMLDOMDocument);
9558
9559 while (entry->type)
9560 {
9561 IXMLDOMNode *node = NULL;
9562 VARIANT var, type;
9563 HRESULT hr;
9564
9565 V_VT(&var) = VT_I4;
9566 V_I4(&var) = entry->type;
9567 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9568 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9569
9570 hr = IXMLDOMNode_get_dataType(node, NULL);
9571 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9572
9573 VariantInit(&type);
9574 hr = IXMLDOMNode_get_dataType(node, &type);
9575 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9576 hr, entry->hr, entry->type);
9577 ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9578 V_VT(&type), entry->vt, entry->type);
9579 VariantClear(&type);
9580
9581 IXMLDOMNode_Release(node);
9582
9583 entry++;
9584 }
9585
9586 IXMLDOMDocument_Release(doc);
9587 free_bstrs();
9588 }
9589
9590 typedef struct _get_node_typestring_t {
9591 DOMNodeType type;
9592 const char *string;
9593 } get_node_typestring_t;
9594
9595 static const get_node_typestring_t get_node_typestring[] = {
9596 { NODE_ELEMENT, "element" },
9597 { NODE_ATTRIBUTE, "attribute" },
9598 { NODE_TEXT, "text" },
9599 { NODE_CDATA_SECTION , "cdatasection" },
9600 { NODE_ENTITY_REFERENCE, "entityreference" },
9601 { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9602 { NODE_COMMENT, "comment" },
9603 { NODE_DOCUMENT_FRAGMENT, "documentfragment" },
9604 { 0 }
9605 };
9606
9607 static void test_get_nodeTypeString(void)
9608 {
9609 const get_node_typestring_t *entry = get_node_typestring;
9610 IXMLDOMDocument *doc;
9611 HRESULT hr;
9612 BSTR str;
9613
9614 doc = create_document(&IID_IXMLDOMDocument);
9615
9616 hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9617 ok(hr == S_OK, "got 0x%08x\n", hr);
9618 ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9619 SysFreeString(str);
9620
9621 while (entry->type)
9622 {
9623 IXMLDOMNode *node = NULL;
9624 VARIANT var;
9625
9626 V_VT(&var) = VT_I4;
9627 V_I4(&var) = entry->type;
9628 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9629 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9630
9631 hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9632 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9633
9634 hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9635 ok(hr == S_OK, "got 0x%08x\n", hr);
9636 ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9637 wine_dbgstr_w(str), entry->string, entry->type);
9638 SysFreeString(str);
9639 IXMLDOMNode_Release(node);
9640
9641 entry++;
9642 }
9643
9644 IXMLDOMDocument_Release(doc);
9645 free_bstrs();
9646 }
9647
9648 typedef struct _get_attributes_t {
9649 DOMNodeType type;
9650 HRESULT hr;
9651 } get_attributes_t;
9652
9653 static const get_attributes_t get_attributes[] = {
9654 { NODE_ATTRIBUTE, S_FALSE },
9655 { NODE_TEXT, S_FALSE },
9656 { NODE_CDATA_SECTION , S_FALSE },
9657 { NODE_ENTITY_REFERENCE, S_FALSE },
9658 { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9659 { NODE_COMMENT, S_FALSE },
9660 { NODE_DOCUMENT_FRAGMENT, S_FALSE },
9661 { 0 }
9662 };
9663
9664 static void test_get_attributes(void)
9665 {
9666 const get_attributes_t *entry = get_attributes;
9667 IXMLDOMNamedNodeMap *map;
9668 IXMLDOMDocument *doc, *doc2;
9669 IXMLDOMNode *node, *node2;
9670 IXMLDOMElement *elem;
9671 VARIANT_BOOL b;
9672 HRESULT hr;
9673 VARIANT v;
9674 BSTR str;
9675 LONG length;
9676
9677 doc = create_document(&IID_IXMLDOMDocument);
9678
9679 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9680 ok(hr == S_OK, "got %08x\n", hr);
9681
9682 hr = IXMLDOMDocument_get_attributes(doc, NULL);
9683 ok(hr == E_INVALIDARG, "got %08x\n", hr);
9684
9685 map = (void*)0xdeadbeef;
9686 hr = IXMLDOMDocument_get_attributes(doc, &map);
9687 ok(hr == S_FALSE, "got %08x\n", hr);
9688 ok(map == NULL, "got %p\n", map);
9689
9690 /* first child is <?xml ?> */
9691 hr = IXMLDOMDocument_get_firstChild(doc, &node);
9692 ok(hr == S_OK, "got %08x\n", hr);
9693
9694 hr = IXMLDOMNode_get_attributes(node, &map);
9695 ok(hr == S_OK, "got %08x\n", hr);
9696
9697 node2 = (void*)0xdeadbeef;
9698 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("attr"), &node2);
9699 ok(hr == S_FALSE, "got %08x\n", hr);
9700 ok(node2 == NULL, "got %p\n", node2);
9701
9702 length = -1;
9703 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9704 EXPECT_HR(hr, S_OK);
9705 todo_wine ok(length == 1, "got %d\n", length);
9706
9707 if (hr == S_OK && length == 1)
9708 {
9709 IXMLDOMAttribute *attr;
9710 DOMNodeType type;
9711 VARIANT v;
9712
9713 node2 = NULL;
9714 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9715 EXPECT_HR(hr, S_OK);
9716 ok(node != NULL, "got %p\n", node2);
9717
9718 hr = IXMLDOMNode_get_nodeName(node2, &str);
9719 EXPECT_HR(hr, S_OK);
9720 ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9721 SysFreeString(str);
9722
9723 length = -1;
9724 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9725 EXPECT_HR(hr, S_OK);
9726 ok(length == 1, "got %d\n", length);
9727
9728 type = -1;
9729 hr = IXMLDOMNode_get_nodeType(node2, &type);
9730 EXPECT_HR(hr, S_OK);
9731 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9732
9733 hr = IXMLDOMNode_get_xml(node, &str);
9734 EXPECT_HR(hr, S_OK);
9735 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9736 SysFreeString(str);
9737
9738 hr = IXMLDOMNode_get_text(node, &str);
9739 EXPECT_HR(hr, S_OK);
9740 ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9741 SysFreeString(str);
9742
9743 hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9744 EXPECT_HR(hr, S_OK);
9745
9746 length = -1;
9747 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9748 EXPECT_HR(hr, S_OK);
9749 ok(length == 0, "got %d\n", length);
9750
9751 hr = IXMLDOMNode_get_xml(node, &str);
9752 EXPECT_HR(hr, S_OK);
9753 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9754 SysFreeString(str);
9755
9756 hr = IXMLDOMNode_get_text(node, &str);
9757 EXPECT_HR(hr, S_OK);
9758 ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9759 SysFreeString(str);
9760
9761 IXMLDOMNamedNodeMap_Release(map);
9762
9763 hr = IXMLDOMNode_get_attributes(node, &map);
9764 ok(hr == S_OK, "got %08x\n", hr);
9765
9766 length = -1;
9767 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9768 EXPECT_HR(hr, S_OK);
9769 ok(length == 0, "got %d\n", length);
9770
9771 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9772 EXPECT_HR(hr, S_OK);
9773
9774 V_VT(&v) = VT_BSTR;
9775 V_BSTR(&v) = _bstr_("UTF-8");
9776 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9777 EXPECT_HR(hr, S_OK);
9778
9779 EXPECT_REF(attr, 2);
9780 hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9781 EXPECT_HR(hr, S_OK);
9782 EXPECT_REF(attr, 2);
9783
9784 hr = IXMLDOMNode_get_attributes(node, &map);
9785 ok(hr == S_OK, "got %08x\n", hr);
9786
9787 length = -1;
9788 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9789 EXPECT_HR(hr, S_OK);
9790 ok(length == 1, "got %d\n", length);
9791
9792 hr = IXMLDOMNode_get_xml(node, &str);
9793 EXPECT_HR(hr, S_OK);
9794 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9795 SysFreeString(str);
9796
9797 hr = IXMLDOMNode_get_text(node, &str);
9798 EXPECT_HR(hr, S_OK);
9799 ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9800 SysFreeString(str);
9801
9802 IXMLDOMNamedNodeMap_Release(map);
9803 IXMLDOMNode_Release(node2);
9804 }
9805
9806 IXMLDOMNode_Release(node);
9807
9808 /* last child is element */
9809 EXPECT_REF(doc, 1);
9810 hr = IXMLDOMDocument_get_lastChild(doc, &node);
9811 ok(hr == S_OK, "got %08x\n", hr);
9812 EXPECT_REF(doc, 1);
9813
9814 EXPECT_REF(node, 1);
9815 hr = IXMLDOMNode_get_attributes(node, &map);
9816 ok(hr == S_OK, "got %08x\n", hr);
9817 EXPECT_REF(node, 1);
9818 EXPECT_REF(doc, 1);
9819
9820 EXPECT_REF(map, 1);
9821 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9822 ok(hr == S_OK, "got %08x\n", hr);
9823 EXPECT_REF(node, 1);
9824 EXPECT_REF(node2, 1);
9825 EXPECT_REF(map, 1);
9826 EXPECT_REF(doc, 1);
9827 IXMLDOMNode_Release(node2);
9828
9829 /* release node before map release, map still works */
9830 IXMLDOMNode_Release(node);
9831
9832 length = 0;
9833 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9834 ok(hr == S_OK, "got %08x\n", hr);
9835 ok(length == 1, "got %d\n", length);
9836
9837 node2 = NULL;
9838 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9839 ok(hr == S_OK, "got %08x\n", hr);
9840 EXPECT_REF(node2, 1);
9841 IXMLDOMNode_Release(node2);
9842
9843 IXMLDOMNamedNodeMap_Release(map);
9844
9845 /* append created element a different document, map still works */
9846 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
9847 ok(hr == S_OK, "createElement failed: %08x\n", hr);
9848
9849 V_VT(&v) = VT_I4;
9850 V_I4(&v) = 1;
9851 hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v);
9852 ok(hr == S_OK, "setAttribute failed: %08x\n", hr);
9853
9854 hr = IXMLDOMElement_get_attributes(elem, &map);
9855 ok(hr == S_OK, "get_attributes failed: %08x\n", hr);
9856
9857 length = 0;
9858 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9859 ok(hr == S_OK, "got %08x\n", hr);
9860 ok(length == 1, "got %d\n", length);
9861
9862 doc2 = create_document(&IID_IXMLDOMDocument);
9863
9864 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node);
9865 ok(hr == S_OK, "appendChild failed: %08x\n", hr);
9866 ok(node == (IXMLDOMNode*)elem, "node != elem\n");
9867 IXMLDOMNode_Release(node);
9868 IXMLDOMElement_Release(elem);
9869 IXMLDOMDocument_Release(doc2);
9870
9871 length = 0;
9872 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9873 ok(hr == S_OK, "got %08x\n", hr);
9874 ok(length == 1, "got %d\n", length);
9875
9876 IXMLDOMNamedNodeMap_Release(map);
9877
9878 while (entry->type)
9879 {
9880 VARIANT var;
9881
9882 node = NULL;
9883
9884 V_VT(&var) = VT_I4;
9885 V_I4(&var) = entry->type;
9886 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9887 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9888
9889 hr = IXMLDOMNode_get_attributes(node, NULL);
9890 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9891
9892 map = (void*)0xdeadbeef;
9893 hr = IXMLDOMNode_get_attributes(node, &map);
9894 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9895 hr, entry->hr, entry->type);
9896 ok(map == NULL, "got %p\n", map);
9897
9898 IXMLDOMNode_Release(node);
9899
9900 entry++;
9901 }
9902
9903 IXMLDOMDocument_Release(doc);
9904 free_bstrs();
9905 }
9906
9907 static void test_selection(void)
9908 {
9909 IXMLDOMSelection *selection, *selection2;
9910 IEnumVARIANT *enum1, *enum2, *enum3;
9911 IXMLDOMNodeList *list;
9912 IUnknown *unk1, *unk2;
9913 IXMLDOMDocument *doc;
9914 IDispatchEx *dispex;
9915 IXMLDOMNode *node;
9916 IDispatch *disp;
9917 VARIANT_BOOL b;
9918 HRESULT hr;
9919 DISPID did;
9920 VARIANT v;
9921 BSTR name;
9922 ULONG ret;
9923 LONG len;
9924
9925 doc = create_document(&IID_IXMLDOMDocument);
9926
9927 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
9928 EXPECT_HR(hr, S_OK);
9929
9930 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
9931 EXPECT_HR(hr, S_OK);
9932
9933 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9934 EXPECT_HR(hr, S_OK);
9935 IXMLDOMSelection_Release(selection);
9936
9937 /* collection disp id */
9938 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
9939 EXPECT_HR(hr, S_OK);
9940 did = 0;
9941 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
9942 EXPECT_HR(hr, S_OK);
9943 ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
9944 len = 0;
9945 hr = IXMLDOMSelection_get_length(selection, &len);
9946 EXPECT_HR(hr, S_OK);
9947 ok(len == 1, "got %d\n", len);
9948 hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
9949 EXPECT_HR(hr, S_OK);
9950 ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
9951 IDispatchEx_Release(dispex);
9952
9953 /* IEnumVARIANT tests */
9954 enum1 = NULL;
9955 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
9956 EXPECT_HR(hr, S_OK);
9957 ok(enum1 != NULL, "got %p\n", enum1);
9958 EXPECT_REF(enum1, 2);
9959
9960 EXPECT_REF(selection, 1);
9961 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1);
9962 EXPECT_HR(hr, S_OK);
9963 EXPECT_REF(selection, 2);
9964 EXPECT_REF(enum1, 2);
9965
9966 /* enumerator and selection object return same IUnknown* */
9967 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
9968 EXPECT_HR(hr, S_OK);
9969 EXPECT_REF(selection, 3);
9970 EXPECT_REF(enum1, 2);
9971 ok(unk2 == unk1, "got %p, %p\n", unk1, unk2);
9972 IUnknown_Release(unk2);
9973
9974 EXPECT_REF(selection, 2);
9975 IEnumVARIANT_AddRef(enum1);
9976 EXPECT_REF(selection, 2);
9977 IEnumVARIANT_Release(enum1);
9978
9979 enum3 = NULL;
9980 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
9981 EXPECT_HR(hr, S_OK);
9982 ok(enum3 != NULL, "got %p\n", enum3);
9983 ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
9984 EXPECT_REF(enum1, 3);
9985 IEnumVARIANT_Release(enum3);
9986
9987 EXPECT_REF(selection, 2);
9988 EXPECT_REF(enum1, 2);
9989
9990 enum2 = NULL;
9991 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9992 EXPECT_HR(hr, S_OK);
9993 ok(enum2 != NULL, "got %p\n", enum2);
9994
9995 EXPECT_REF(selection, 3);
9996 EXPECT_REF(enum1, 2);
9997 EXPECT_REF(enum2, 1);
9998
9999 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10000
10001 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
10002 EXPECT_HR(hr, S_OK);
10003 EXPECT_REF(selection, 3);
10004 EXPECT_REF(enum2, 2);
10005 ok(unk2 != unk1, "got %p, %p\n", unk1, unk2);
10006 IUnknown_Release(unk2);
10007 IUnknown_Release(unk1);
10008
10009 selection2 = NULL;
10010 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10011 EXPECT_HR(hr, S_OK);
10012 ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10013 EXPECT_REF(selection, 3);
10014 EXPECT_REF(enum1, 2);
10015
10016 IXMLDOMSelection_Release(selection2);
10017
10018 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10019 EXPECT_HR(hr, S_OK);
10020 EXPECT_REF(selection, 3);
10021 IDispatch_Release(disp);
10022
10023 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10024 EXPECT_HR(hr, S_OK);
10025 ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10026 EXPECT_REF(selection, 2);
10027 EXPECT_REF(enum1, 3);
10028
10029 IEnumVARIANT_Release(enum1);
10030 IEnumVARIANT_Release(enum2);
10031 IEnumVARIANT_Release(enum3);
10032
10033 enum1 = NULL;
10034 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10035 EXPECT_HR(hr, S_OK);
10036 ok(enum1 != NULL, "got %p\n", enum1);
10037 EXPECT_REF(enum1, 1);
10038 EXPECT_REF(selection, 2);
10039
10040 enum2 = NULL;
10041 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10042 EXPECT_HR(hr, S_OK);
10043 ok(enum2 != NULL, "got %p\n", enum2);
10044 EXPECT_REF(enum2, 1);
10045 EXPECT_REF(selection, 3);
10046
10047 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10048
10049 IEnumVARIANT_AddRef(enum1);
10050 EXPECT_REF(selection, 3);
10051 EXPECT_REF(enum1, 2);
10052 EXPECT_REF(enum2, 1);
10053 IEnumVARIANT_Release(enum1);
10054
10055 IEnumVARIANT_Release(enum1);
10056 IEnumVARIANT_Release(enum2);
10057
10058 EXPECT_REF(selection, 1);
10059
10060 IXMLDOMNodeList_Release(list);
10061
10062 hr = IXMLDOMDocument_get_childNodes(doc, &list);
10063 EXPECT_HR(hr, S_OK);
10064
10065 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10066 EXPECT_HR(hr, E_NOINTERFACE);
10067
10068 IXMLDOMNodeList_Release(list);
10069
10070 /* test if IEnumVARIANT touches selection context */
10071 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
10072 EXPECT_HR(hr, S_OK);
10073
10074 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10075 EXPECT_HR(hr, S_OK);
10076
10077 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10078 EXPECT_HR(hr, S_OK);
10079
10080 len = 0;
10081 hr = IXMLDOMSelection_get_length(selection, &len);
10082 EXPECT_HR(hr, S_OK);
10083 ok(len == 4, "got %d\n", len);
10084
10085 enum1 = NULL;
10086 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10087 EXPECT_HR(hr, S_OK);
10088
10089 /* no-op if zero count */
10090 V_VT(&v) = VT_I2;
10091 hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10092 EXPECT_HR(hr, S_OK);
10093 ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10094
10095 /* positive count, null array pointer */
10096 hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10097 EXPECT_HR(hr, E_INVALIDARG);
10098
10099 ret = 1;
10100 hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10101 EXPECT_HR(hr, E_INVALIDARG);
10102 ok(ret == 0, "got %d\n", ret);
10103
10104 V_VT(&v) = VT_I2;
10105 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10106 EXPECT_HR(hr, S_OK);
10107 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10108
10109 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10110 EXPECT_HR(hr, S_OK);
10111 hr = IXMLDOMNode_get_nodeName(node, &name);
10112 EXPECT_HR(hr, S_OK);
10113 ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10114 SysFreeString(name);
10115 IXMLDOMNode_Release(node);
10116 VariantClear(&v);
10117
10118 /* list cursor is updated */
10119 hr = IXMLDOMSelection_nextNode(selection, &node);
10120 EXPECT_HR(hr, S_OK);
10121 hr = IXMLDOMNode_get_nodeName(node, &name);
10122 EXPECT_HR(hr, S_OK);
10123 ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10124 IXMLDOMNode_Release(node);
10125 SysFreeString(name);
10126
10127 V_VT(&v) = VT_I2;
10128 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10129 EXPECT_HR(hr, S_OK);
10130 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10131 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10132 EXPECT_HR(hr, S_OK);
10133 hr = IXMLDOMNode_get_nodeName(node, &name);
10134 EXPECT_HR(hr, S_OK);
10135 ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10136 SysFreeString(name);
10137 IXMLDOMNode_Release(node);
10138 VariantClear(&v);
10139 IEnumVARIANT_Release(enum1);
10140
10141 hr = IXMLDOMSelection_nextNode(selection, &node);
10142 EXPECT_HR(hr, S_OK);
10143 hr = IXMLDOMNode_get_nodeName(node, &name);
10144 EXPECT_HR(hr, S_OK);
10145 ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10146 IXMLDOMNode_Release(node);
10147 SysFreeString(name);
10148
10149 IXMLDOMSelection_Release(selection);
10150 IXMLDOMNodeList_Release(list);
10151 IXMLDOMDocument_Release(doc);
10152
10153 free_bstrs();
10154 }
10155
10156 static void write_to_file(const char *name, const char *data)
10157 {
10158 DWORD written;
10159 HANDLE hfile;
10160 BOOL ret;
10161
10162 hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10163 ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name);
10164
10165 ret = WriteFile(hfile, data, strlen(data), &written, NULL);
10166 ok(ret, "WriteFile failed: %s, %d\n", name, GetLastError());
10167
10168 CloseHandle(hfile);
10169 }
10170
10171 static void test_load(void)
10172 {
10173 IXMLDOMDocument *doc, *doc2;
10174 BSTR pathW, bstr1, bstr2;
10175 IXMLDOMNodeList *list;
10176 IXMLDOMElement *elem;
10177 char path[MAX_PATH];
10178 VARIANT_BOOL b;
10179 VARIANT src;
10180 HRESULT hr;
10181 void* ptr;
10182
10183 GetTempPathA(MAX_PATH, path);
10184 strcat(path, "winetest.xml");
10185
10186 /* prepare a file */
10187 write_to_file(path, win1252xml);
10188
10189 doc = create_document(&IID_IXMLDOMDocument);
10190
10191 /* null pointer as input */
10192 V_VT(&src) = VT_UNKNOWN;
10193 V_UNKNOWN(&src) = NULL;
10194 hr = IXMLDOMDocument_load(doc, src, &b);
10195 EXPECT_HR(hr, E_INVALIDARG);
10196 ok(b == VARIANT_FALSE, "got %d\n", b);
10197
10198 pathW = _bstr_(path);
10199
10200 /* load from path: VT_BSTR */
10201 V_VT(&src) = VT_BSTR;
10202 V_BSTR(&src) = pathW;
10203 hr = IXMLDOMDocument_load(doc, src, &b);
10204 EXPECT_HR(hr, S_OK);
10205 ok(b == VARIANT_TRUE, "got %d\n", b);
10206
10207 bstr1 = NULL;
10208 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10209 ok(hr == S_OK, "got 0x%08x\n", hr);
10210 SysFreeString(bstr1);
10211
10212 /* load from a path: VT_BSTR|VT_BYREF */
10213 V_VT(&src) = VT_BSTR | VT_BYREF;
10214 V_BSTRREF(&src) = &pathW;
10215 hr = IXMLDOMDocument_load(doc, src, &b);
10216 EXPECT_HR(hr, S_OK);
10217 ok(b == VARIANT_TRUE, "got %d\n", b);
10218
10219 bstr1 = NULL;
10220 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10221 ok(hr == S_OK, "got 0x%08x\n", hr);
10222
10223 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
10224 ok(hr == S_OK, "got 0x%08x\n", hr);
10225
10226 /* create another instance for the same document, check url */
10227 hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
10228 ok(hr == S_OK, "got 0x%08x\n", hr);
10229
10230 hr = IXMLDOMDocument_get_url(doc, &bstr2);
10231 ok(hr == S_OK, "got 0x%08x\n", hr);
10232 ok(!lstrcmpW(bstr1, bstr2), "got %s\n", wine_dbgstr_w(bstr2));
10233
10234 IXMLDOMDocument_Release(doc2);
10235 IXMLDOMElement_Release(elem);
10236
10237 SysFreeString(bstr1);
10238 SysFreeString(bstr2);
10239
10240 /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10241 V_VT(&src) = VT_BSTR | VT_BYREF;
10242 V_BSTRREF(&src) = NULL;
10243 hr = IXMLDOMDocument_load(doc, src, &b);
10244 EXPECT_HR(hr, E_INVALIDARG);
10245 ok(b == VARIANT_FALSE, "got %d\n", b);
10246
10247 bstr1 = NULL;
10248 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10249 ok(hr == S_OK, "got 0x%08x\n", hr);
10250 SysFreeString(bstr1);
10251
10252 DeleteFileA(path);
10253
10254 /* load from existing path, no xml content */
10255 write_to_file(path, nocontent);
10256
10257 V_VT(&src) = VT_BSTR;
10258 V_BSTR(&src) = pathW;
10259 b = VARIANT_TRUE;
10260 hr = IXMLDOMDocument_load(doc, src, &b);
10261 ok(hr == S_FALSE, "got 0x%08x\n", hr);
10262 ok(b == VARIANT_FALSE, "got %d\n", b);
10263
10264 bstr1 = (void *)0xdeadbeef;
10265 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10266 ok(hr == S_FALSE, "got 0x%08x\n", hr);
10267 ok(bstr1 == NULL, "got %p\n", bstr1);
10268
10269 DeleteFileA(path);
10270 IXMLDOMDocument_Release(doc);
10271
10272 doc = create_document(&IID_IXMLDOMDocument);
10273
10274 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10275 EXPECT_HR(hr, S_OK);
10276 ok(b == VARIANT_TRUE, "got %d\n", b);
10277
10278 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10279 EXPECT_HR(hr, S_OK);
10280 bstr1 = _bstr_(list_to_string(list));
10281
10282 hr = IXMLDOMNodeList_reset(list);
10283 EXPECT_HR(hr, S_OK);
10284
10285 IXMLDOMDocument_Release(doc);
10286
10287 doc = create_document(&IID_IXMLDOMDocument);
10288
10289 VariantInit(&src);
10290 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10291 V_VT(&src) = VT_ARRAY|VT_UI1;
10292 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10293 ptr = NULL;
10294 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10295 EXPECT_HR(hr, S_OK);
10296 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10297
10298 memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10299 hr = SafeArrayUnlock(V_ARRAY(&src));
10300 EXPECT_HR(hr, S_OK);
10301
10302 hr = IXMLDOMDocument_load(doc, src, &b);
10303 EXPECT_HR(hr, S_OK);
10304 ok(b == VARIANT_TRUE, "got %d\n", b);
10305
10306 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10307 EXPECT_HR(hr, S_OK);
10308 bstr2 = _bstr_(list_to_string(list));
10309
10310 hr = IXMLDOMNodeList_reset(list);
10311 EXPECT_HR(hr, S_OK);
10312
10313 ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10314 wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10315
10316 IXMLDOMDocument_Release(doc);
10317 IXMLDOMNodeList_Release(list);
10318 VariantClear(&src);
10319
10320 /* UTF-16 isn't accepted */
10321 doc = create_document(&IID_IXMLDOMDocument);
10322
10323 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10324 V_VT(&src) = VT_ARRAY|VT_UI1;
10325 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10326 ptr = NULL;
10327 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10328 EXPECT_HR(hr, S_OK);
10329 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10330
10331 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10332 hr = SafeArrayUnlock(V_ARRAY(&src));
10333 EXPECT_HR(hr, S_OK);
10334
10335 hr = IXMLDOMDocument_load(doc, src, &b);
10336 todo_wine EXPECT_HR(hr, S_FALSE);
10337 todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10338
10339 VariantClear(&src);
10340
10341 /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10342 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10343 V_VT(&src) = VT_ARRAY|VT_UI2;
10344 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10345 ptr = NULL;
10346 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10347 EXPECT_HR(hr, S_OK);
10348 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10349
10350 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10351 hr = SafeArrayUnlock(V_ARRAY(&src));
10352 EXPECT_HR(hr, S_OK);
10353
10354 hr = IXMLDOMDocument_load(doc, src, &b);
10355 todo_wine EXPECT_HR(hr, E_INVALIDARG);
10356 ok(b == VARIANT_FALSE, "got %d\n", b);
10357
10358 VariantClear(&src);
10359 IXMLDOMDocument_Release(doc);
10360
10361 free_bstrs();
10362 }
10363
10364 static void test_domobj_dispex(IUnknown *obj)
10365 {
10366 static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0};
10367 DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10368 IDispatchEx *dispex;
10369 IUnknown *unk;
10370 DWORD props;
10371 UINT ticnt;
10372 HRESULT hr;
10373 BSTR name;
10374
10375 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10376 EXPECT_HR(hr, S_OK);
10377 if (FAILED(hr)) return;
10378
10379 ticnt = 0;
10380 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10381 EXPECT_HR(hr, S_OK);
10382 ok(ticnt == 1, "ticnt=%u\n", ticnt);
10383
10384 name = SysAllocString(szstar);
10385 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10386 EXPECT_HR(hr, E_NOTIMPL);
10387 SysFreeString(name);
10388
10389 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10390 EXPECT_HR(hr, E_NOTIMPL);
10391
10392 props = 0;
10393 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10394 EXPECT_HR(hr, E_NOTIMPL);
10395 ok(props == 0, "expected 0 got %d\n", props);
10396
10397 hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10398 EXPECT_HR(hr, E_NOTIMPL);
10399 if (SUCCEEDED(hr)) SysFreeString(name);
10400
10401 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10402 EXPECT_HR(hr, E_NOTIMPL);
10403
10404 unk = (IUnknown*)0xdeadbeef;
10405 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10406 EXPECT_HR(hr, E_NOTIMPL);
10407 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk);
10408
10409 name = SysAllocString(testW);
10410 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid);
10411 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
10412 SysFreeString(name);
10413
10414 IDispatchEx_Release(dispex);
10415 }
10416
10417 static void test_mxnamespacemanager(void)
10418 {
10419 static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10420 IMXNamespacePrefixes *prefixes;
10421 IVBMXNamespaceManager *mgr2;
10422 IMXNamespaceManager *nsmgr;
10423 IUnknown *unk1, *unk2;
10424 WCHAR buffW[250];
10425 IDispatch *disp;
10426 IUnknown *unk;
10427 HRESULT hr;
10428 INT len;
10429
10430 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10431 &IID_IMXNamespaceManager, (void**)&nsmgr);
10432 EXPECT_HR(hr, S_OK);
10433
10434 /* IMXNamespaceManager inherits from IUnknown */
10435 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10436 EXPECT_HR(hr, S_OK);
10437 IDispatch_Release(disp);
10438
10439 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10440 EXPECT_HR(hr, S_OK);
10441
10442 EXPECT_REF(nsmgr, 2);
10443 EXPECT_REF(mgr2, 2);
10444 prefixes = NULL;
10445 hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
10446 todo_wine
10447 ok(hr == S_OK, "got 0x%08x\n", hr);
10448 if (hr == S_OK)
10449 {
10450 IDispatchEx *dispex;
10451 VARIANT arg, ret;
10452 DISPPARAMS dispparams;
10453
10454 ok(prefixes != NULL, "got %p\n", prefixes);
10455 EXPECT_REF(nsmgr, 2);
10456 EXPECT_REF(mgr2, 2);
10457 EXPECT_REF(prefixes, 1);
10458
10459 IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1);
10460 IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2);
10461
10462 EXPECT_REF(mgr2, 3);
10463 EXPECT_REF(prefixes, 2);
10464
10465 IUnknown_Release(unk1);
10466 IUnknown_Release(unk2);
10467
10468 hr = IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IDispatchEx, (void**)&dispex);
10469 ok(hr == S_OK, "got 0x%08x\n", hr);
10470
10471 V_VT(&arg) = VT_I4;
10472 V_I4(&arg) = 0;
10473 dispparams.cArgs = 1;
10474 dispparams.cNamedArgs = 0;
10475 dispparams.rgdispidNamedArgs = NULL;
10476 dispparams.rgvarg = &arg;
10477
10478 V_VT(&ret) = VT_EMPTY;
10479 V_DISPATCH(&ret) = (void*)0x1;
10480 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
10481 ok(hr == S_OK, "got 0x%08x\n", hr);
10482 ok(V_VT(&ret) == VT_BSTR, "got %d\n", V_VT(&ret));
10483 ok(V_BSTR(&ret) != NULL, "got %p\n", V_BSTR(&ret));
10484 VariantClear(&ret);
10485
10486 IDispatchEx_Release(dispex);
10487 IMXNamespacePrefixes_Release(prefixes);
10488 }
10489 IVBMXNamespaceManager_Release(mgr2);
10490
10491 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10492 EXPECT_HR(hr, S_OK);
10493
10494 /* prefix already added */
10495 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10496 EXPECT_HR(hr, S_FALSE);
10497
10498 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10499 EXPECT_HR(hr, E_INVALIDARG);
10500
10501 /* "xml" and "xmlns" are not allowed here */
10502 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10503 EXPECT_HR(hr, E_INVALIDARG);
10504
10505 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10506 EXPECT_HR(hr, E_INVALIDARG);
10507 todo_wine {
10508 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10509 EXPECT_HR(hr, E_FAIL);
10510 }
10511 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10512 EXPECT_HR(hr, E_POINTER);
10513
10514 len = -1;
10515 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10516 EXPECT_HR(hr, S_OK);
10517 ok(len == 3, "got %d\n", len);
10518
10519 len = -1;
10520 buffW[0] = 0x1;
10521 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10522 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10523 ok(len == -1, "got %d\n", len);
10524 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10525
10526 len = 10;
10527 buffW[0] = 0x1;
10528 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10529 EXPECT_HR(hr, S_OK);
10530 ok(len == 3, "got %d\n", len);
10531 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10532
10533 /* getURI */
10534 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10535 EXPECT_HR(hr, E_INVALIDARG);
10536
10537 len = -1;
10538 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10539 EXPECT_HR(hr, E_INVALIDARG);
10540 ok(len == -1, "got %d\n", len);
10541
10542 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10543 EXPECT_HR(hr, E_POINTER);
10544
10545 len = -1;
10546 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10547 EXPECT_HR(hr, S_OK);
10548 /* length of "xml" uri is constant */
10549 ok(len == strlen(xmluriA), "got %d\n", len);
10550
10551 len = 100;
10552 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10553 EXPECT_HR(hr, S_OK);
10554 ok(len == strlen(xmluriA), "got %d\n", len);
10555 ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10556
10557 len = strlen(xmluriA)-1;
10558 buffW[0] = 0x1;
10559 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10560 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10561 ok(len == strlen(xmluriA)-1, "got %d\n", len);
10562 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10563
10564 /* prefix xml1 not defined */
10565 len = -1;
10566 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10567 EXPECT_HR(hr, S_FALSE);
10568 ok(len == 0, "got %d\n", len);
10569
10570 len = 100;
10571 buffW[0] = 0x1;
10572 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10573 EXPECT_HR(hr, S_FALSE);
10574 ok(buffW[0] == 0, "got %x\n", buffW[0]);
10575 ok(len == 0, "got %d\n", len);
10576
10577 /* IDispatchEx tests */
10578 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10579 EXPECT_HR(hr, S_OK);
10580 test_domobj_dispex(unk);
10581 IUnknown_Release(unk);
10582
10583 IMXNamespaceManager_Release(nsmgr);
10584
10585 /* ::getPrefix() */
10586 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10587 &IID_IMXNamespaceManager, (void**)&nsmgr);
10588 EXPECT_HR(hr, S_OK);
10589
10590 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10591 EXPECT_HR(hr, E_INVALIDARG);
10592
10593 len = -1;
10594 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10595 EXPECT_HR(hr, E_INVALIDARG);
10596 ok(len == -1, "got %d\n", len);
10597
10598 len = 100;
10599 buffW[0] = 0x1;
10600 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10601 EXPECT_HR(hr, E_FAIL);
10602 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10603 ok(len == 100, "got %d\n", len);
10604
10605 len = 0;
10606 buffW[0] = 0x1;
10607 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10608 EXPECT_HR(hr, E_FAIL);
10609 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10610 ok(len == 0, "got %d\n", len);
10611
10612 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10613 EXPECT_HR(hr, S_OK);
10614
10615 len = 100;
10616 buffW[0] = 0x1;
10617 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10618 EXPECT_HR(hr, S_OK);
10619 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10620 ok(len == 3, "got %d\n", len);
10621
10622 len = 100;
10623 buffW[0] = 0x1;
10624 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10625 EXPECT_HR(hr, S_OK);
10626 ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10627 ok(len == 3, "got %d\n", len);
10628
10629 /* with null buffer it's possible to get required length */
10630 len = 100;
10631 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10632 EXPECT_HR(hr, S_OK);
10633 ok(len == 3, "got %d\n", len);
10634
10635 len = 0;
10636 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10637 EXPECT_HR(hr, S_OK);
10638 ok(len == 3, "got %d\n", len);
10639
10640 len = 100;
10641 buffW[0] = 0x1;
10642 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10643 EXPECT_HR(hr, E_FAIL);
10644 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10645 ok(len == 100, "got %d\n", len);
10646
10647 len = 100;
10648 buffW[0] = 0x1;
10649 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10650 EXPECT_HR(hr, E_FAIL);
10651 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10652 ok(len == 100, "got %d\n", len);
10653
10654 len = 100;
10655 buffW[0] = 0x1;
10656 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10657 EXPECT_HR(hr, E_INVALIDARG);
10658 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10659 ok(len == 100, "got %d\n", len);
10660
10661 len = 100;
10662 buffW[0] = 0x1;
10663 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10664 EXPECT_HR(hr, E_INVALIDARG);
10665 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10666 ok(len == 100, "got %d\n", len);
10667
10668 len = 100;
10669 buffW[0] = 0x1;
10670 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10671 EXPECT_HR(hr, E_INVALIDARG);
10672 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10673 ok(len == 100, "got %d\n", len);
10674
10675 len = 100;
10676 buffW[0] = 0x1;
10677 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10678 EXPECT_HR(hr, E_FAIL);
10679 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10680 ok(len == 100, "got %d\n", len);
10681
10682 len = 100;
10683 buffW[0] = 0x1;
10684 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10685 EXPECT_HR(hr, E_INVALIDARG);
10686 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10687 ok(len == 100, "got %d\n", len);
10688
10689 /* declare another one, indices are shifted */
10690 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10691 EXPECT_HR(hr, S_OK);
10692
10693 len = 100;
10694 buffW[0] = 0x1;
10695 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10696 EXPECT_HR(hr, S_OK);
10697 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10698 ok(len == 3, "got %d\n", len);
10699
10700 len = 100;
10701 buffW[0] = 0x1;
10702 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10703 EXPECT_HR(hr, S_OK);
10704 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10705 ok(len == 3, "got %d\n", len);
10706
10707 len = 100;
10708 buffW[0] = 0x1;
10709 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10710 EXPECT_HR(hr, E_FAIL);
10711 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10712 ok(len == 100, "got %d\n", len);
10713
10714 len = 100;
10715 buffW[0] = 0x1;
10716 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10717 EXPECT_HR(hr, E_INVALIDARG);
10718 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10719 ok(len == 100, "got %d\n", len);
10720
10721 IMXNamespaceManager_Release(nsmgr);
10722
10723 /* push/pop tests */
10724 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10725 &IID_IMXNamespaceManager, (void**)&nsmgr);
10726 EXPECT_HR(hr, S_OK);
10727
10728 /* pop with empty stack */
10729 hr = IMXNamespaceManager_popContext(nsmgr);
10730 EXPECT_HR(hr, E_FAIL);
10731
10732 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10733 EXPECT_HR(hr, S_OK);
10734
10735 len = 100;
10736 buffW[0] = 0x1;
10737 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10738 EXPECT_HR(hr, S_OK);
10739 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10740 ok(len == 3, "got %d\n", len);
10741
10742 hr = IMXNamespaceManager_pushContext(nsmgr);
10743 EXPECT_HR(hr, S_OK);
10744
10745 len = 100;
10746 buffW[0] = 0x1;
10747 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10748 EXPECT_HR(hr, S_OK);
10749 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10750 ok(len == 3, "got %d\n", len);
10751
10752 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10753 EXPECT_HR(hr, S_OK);
10754
10755 len = 100;
10756 buffW[0] = 0x1;
10757 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10758 EXPECT_HR(hr, S_OK);
10759 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10760 ok(len == 3, "got %d\n", len);
10761
10762 hr = IMXNamespaceManager_pushContext(nsmgr);
10763 EXPECT_HR(hr, S_OK);
10764 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
10765 EXPECT_HR(hr, S_OK);
10766
10767 len = 100;
10768 buffW[0] = 0x1;
10769 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10770 EXPECT_HR(hr, S_OK);
10771 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10772 ok(len == 3, "got %d\n", len);
10773
10774 len = 100;
10775 buffW[0] = 0x1;
10776 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10777 EXPECT_HR(hr, S_OK);
10778 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10779 ok(len == 3, "got %d\n", len);
10780
10781 hr = IMXNamespaceManager_popContext(nsmgr);
10782 EXPECT_HR(hr, S_OK);
10783
10784 hr = IMXNamespaceManager_popContext(nsmgr);
10785 EXPECT_HR(hr, S_OK);
10786
10787 len = 100;
10788 buffW[0] = 0x1;
10789 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10790 EXPECT_HR(hr, E_FAIL);
10791 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10792 ok(len == 100, "got %d\n", len);
10793
10794 len = 100;
10795 buffW[0] = 0x1;
10796 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10797 EXPECT_HR(hr, S_OK);
10798 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10799 ok(len == 3, "got %d\n", len);
10800
10801 IMXNamespaceManager_Release(nsmgr);
10802
10803 free_bstrs();
10804 }
10805
10806 static void test_mxnamespacemanager_override(void)
10807 {
10808 IMXNamespaceManager *nsmgr;
10809 WCHAR buffW[250];
10810 VARIANT_BOOL b;
10811 HRESULT hr;
10812 INT len;
10813
10814 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10815 &IID_IMXNamespaceManager, (void**)&nsmgr);
10816 EXPECT_HR(hr, S_OK);
10817
10818 len = sizeof(buffW)/sizeof(WCHAR);
10819 buffW[0] = 0;
10820 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10821 EXPECT_HR(hr, S_OK);
10822 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10823
10824 len = sizeof(buffW)/sizeof(WCHAR);
10825 buffW[0] = 0;
10826 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10827 EXPECT_HR(hr, E_FAIL);
10828
10829 hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10830 EXPECT_HR(hr, E_POINTER);
10831
10832 b = VARIANT_FALSE;
10833 hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10834 EXPECT_HR(hr, S_OK);
10835 ok(b == VARIANT_TRUE, "got %d\n", b);
10836
10837 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10838 EXPECT_HR(hr, S_OK);
10839
10840 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10841 EXPECT_HR(hr, S_OK);
10842
10843 len = sizeof(buffW)/sizeof(WCHAR);
10844 buffW[0] = 0;
10845 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10846 EXPECT_HR(hr, S_OK);
10847 ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10848
10849 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10850 EXPECT_HR(hr, S_OK);
10851
10852 len = sizeof(buffW)/sizeof(WCHAR);
10853 buffW[0] = 0;
10854 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10855 EXPECT_HR(hr, S_OK);
10856 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10857
10858 len = sizeof(buffW)/sizeof(WCHAR);
10859 buffW[0] = 0;
10860 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10861 EXPECT_HR(hr, S_OK);
10862 ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10863
10864 len = sizeof(buffW)/sizeof(WCHAR);
10865 buffW[0] = 0;
10866 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10867 EXPECT_HR(hr, S_OK);
10868 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10869
10870 /* new prefix placed at index 1 always */
10871 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10872 EXPECT_HR(hr, S_OK);
10873
10874 len = sizeof(buffW)/sizeof(WCHAR);
10875 buffW[0] = 0;
10876 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10877 EXPECT_HR(hr, S_OK);
10878 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10879
10880 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10881 todo_wine EXPECT_HR(hr, E_FAIL);
10882
10883 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10884 EXPECT_HR(hr, E_FAIL);
10885
10886 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10887 EXPECT_HR(hr, E_FAIL);
10888
10889 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10890 EXPECT_HR(hr, S_OK);
10891
10892 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10893 EXPECT_HR(hr, S_FALSE);
10894
10895 len = sizeof(buffW)/sizeof(WCHAR);
10896 buffW[0] = 0;
10897 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10898 EXPECT_HR(hr, S_OK);
10899 ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10900
10901 len = sizeof(buffW)/sizeof(WCHAR);
10902 buffW[0] = 0;
10903 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10904 EXPECT_HR(hr, S_OK);
10905 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10906
10907 IMXNamespaceManager_Release(nsmgr);
10908
10909 free_bstrs();
10910 }
10911
10912 static const DOMNodeType nodetypes_test[] =
10913 {
10914 NODE_ELEMENT,
10915 NODE_ATTRIBUTE,
10916 NODE_TEXT,
10917 NODE_CDATA_SECTION,
10918 NODE_ENTITY_REFERENCE,
10919 NODE_PROCESSING_INSTRUCTION,
10920 NODE_COMMENT,
10921 NODE_DOCUMENT_FRAGMENT,
10922 NODE_INVALID
10923 };
10924
10925 static void test_dispex(void)
10926 {
10927 const DOMNodeType *type = nodetypes_test;
10928 IXMLDOMImplementation *impl;
10929 IXMLDOMNodeList *node_list;
10930 IXMLDOMParseError *error;
10931 IXMLDOMNamedNodeMap *map;
10932 IXSLProcessor *processor;
10933 IXSLTemplate *template;
10934 IXMLDOMDocument *doc;
10935 IXMLHTTPRequest *req;
10936 IXMLDOMElement *elem;
10937 IDispatchEx *dispex;
10938 DISPPARAMS dispparams;
10939 IXMLDOMNode *node;
10940 VARIANT arg, ret;
10941 VARIANT_BOOL b;
10942 IUnknown *unk;
10943 HRESULT hr;
10944 DISPID did;
10945
10946 doc = create_document(&IID_IXMLDOMDocument);
10947
10948 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10949 ok(hr == S_OK, "got 0x%08x\n", hr);
10950 test_domobj_dispex(unk);
10951 IUnknown_Release(unk);
10952
10953 for(; *type != NODE_INVALID; type++)
10954 {
10955 IXMLDOMNode *node;
10956 VARIANT v;
10957
10958 V_VT(&v) = VT_I2;
10959 V_I2(&v) = *type;
10960
10961 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10962 ok(hr == S_OK, "failed to create node type %d\n", *type);
10963
10964 IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10965
10966 test_domobj_dispex(unk);
10967 IUnknown_Release(unk);
10968 IXMLDOMNode_Release(node);
10969 }
10970
10971 /* IXMLDOMNodeList */
10972 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10973 EXPECT_HR(hr, S_OK);
10974 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10975 ok(hr == S_OK, "got 0x%08x\n", hr);
10976 test_domobj_dispex(unk);
10977 IUnknown_Release(unk);
10978 IXMLDOMNodeList_Release(node_list);
10979
10980 /* IXMLDOMNodeList for children list */
10981 hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10982 EXPECT_HR(hr, S_OK);
10983 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10984 ok(hr == S_OK, "got 0x%08x\n", hr);
10985 test_domobj_dispex(unk);
10986 IUnknown_Release(unk);
10987
10988 /* collection dispex test, empty collection */
10989 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10990 EXPECT_HR(hr, S_OK);
10991 did = 0;
10992 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10993 EXPECT_HR(hr, S_OK);
10994 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10995 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10996 EXPECT_HR(hr, S_OK);
10997 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10998 IDispatchEx_Release(dispex);
10999
11000 did = -1;
11001 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
11002 ok(hr == S_OK, "got 0x%08x\n", hr);
11003 ok(did == DISPID_VALUE, "got %d\n", did);
11004
11005 V_VT(&arg) = VT_I4;
11006 V_I4(&arg) = 0;
11007 dispparams.cArgs = 0;
11008 dispparams.cNamedArgs = 0;
11009 dispparams.rgdispidNamedArgs = NULL;
11010 dispparams.rgvarg = &arg;
11011
11012 V_VT(&ret) = VT_EMPTY;
11013 V_DISPATCH(&ret) = (void*)0x1;
11014 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11015 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11016 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11017 todo_wine
11018 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11019
11020 V_VT(&arg) = VT_I4;
11021 V_I4(&arg) = 0;
11022 dispparams.cArgs = 2;
11023 dispparams.cNamedArgs = 0;
11024 dispparams.rgdispidNamedArgs = NULL;
11025 dispparams.rgvarg = &arg;
11026
11027 V_VT(&ret) = VT_EMPTY;
11028 V_DISPATCH(&ret) = (void*)0x1;
11029 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11030 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11031 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11032 todo_wine
11033 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11034
11035 V_VT(&arg) = VT_I4;
11036 V_I4(&arg) = 0;
11037 dispparams.cArgs = 1;
11038 dispparams.cNamedArgs = 0;
11039 dispparams.rgdispidNamedArgs = NULL;
11040 dispparams.rgvarg = &arg;
11041
11042 V_VT(&ret) = VT_EMPTY;
11043 V_DISPATCH(&ret) = (void*)0x1;
11044 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11045 ok(hr == S_OK, "got 0x%08x\n", hr);
11046 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11047 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11048
11049 V_VT(&ret) = VT_EMPTY;
11050 V_DISPATCH(&ret) = (void*)0x1;
11051 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11052 ok(hr == S_OK, "got 0x%08x\n", hr);
11053 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11054 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11055
11056 V_VT(&ret) = VT_EMPTY;
11057 V_DISPATCH(&ret) = (void*)0x1;
11058 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11059 ok(hr == S_OK, "got 0x%08x\n", hr);
11060 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11061 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11062
11063 dispparams.cArgs = 0;
11064 dispparams.cNamedArgs = 0;
11065 dispparams.rgdispidNamedArgs = NULL;
11066 dispparams.rgvarg = NULL;
11067
11068 V_VT(&ret) = VT_EMPTY;
11069 V_I4(&ret) = 1;
11070 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11071 ok(hr == S_OK, "got 0x%08x\n", hr);
11072 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11073 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
11074
11075 dispparams.cArgs = 0;
11076 dispparams.cNamedArgs = 0;
11077 dispparams.rgdispidNamedArgs = NULL;
11078 dispparams.rgvarg = NULL;
11079
11080 V_VT(&ret) = VT_EMPTY;
11081 V_I4(&ret) = 1;
11082 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11083 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11084 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11085 todo_wine
11086 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
11087
11088 IXMLDOMNodeList_Release(node_list);
11089
11090 /* IXMLDOMParseError */
11091 hr = IXMLDOMDocument_get_parseError(doc, &error);
11092 EXPECT_HR(hr, S_OK);
11093 IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11094 test_domobj_dispex(unk);
11095
11096 hr = IXMLDOMParseError_QueryInterface(error, &IID_IDispatchEx, (void**)&dispex);
11097 ok(hr == S_OK, "got 0x%08x\n", hr);
11098
11099 V_VT(&arg) = VT_I4;
11100 V_I4(&arg) = 0;
11101 dispparams.cArgs = 1;
11102 dispparams.cNamedArgs = 0;
11103 dispparams.rgdispidNamedArgs = NULL;
11104 dispparams.rgvarg = &arg;
11105
11106 V_VT(&ret) = VT_EMPTY;
11107 V_DISPATCH(&ret) = (void*)0x1;
11108 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11109 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11110 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11111 todo_wine
11112 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11113
11114 IDispatchEx_Release(dispex);
11115
11116 IUnknown_Release(unk);
11117 IXMLDOMParseError_Release(error);
11118
11119 /* IXMLDOMNamedNodeMap */
11120 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
11121 EXPECT_HR(hr, S_OK);
11122
11123 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11124 EXPECT_HR(hr, S_OK);
11125 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11126 EXPECT_HR(hr, S_OK);
11127 IXMLDOMNodeList_Release(node_list);
11128
11129 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11130 EXPECT_HR(hr, S_OK);
11131 IXMLDOMNode_Release(node);
11132 hr = IXMLDOMElement_get_attributes(elem, &map);
11133 EXPECT_HR(hr, S_OK);
11134 IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11135 test_domobj_dispex(unk);
11136 IUnknown_Release(unk);
11137 /* collection dispex test */
11138 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11139 EXPECT_HR(hr, S_OK);
11140 did = 0;
11141 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11142 EXPECT_HR(hr, S_OK);
11143 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11144 IDispatchEx_Release(dispex);
11145 IXMLDOMNamedNodeMap_Release(map);
11146
11147 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11148 EXPECT_HR(hr, S_OK);
11149 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11150 EXPECT_HR(hr, S_OK);
11151 IXMLDOMNodeList_Release(node_list);
11152 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11153 EXPECT_HR(hr, S_OK);
11154 IXMLDOMNode_Release(node);
11155 hr = IXMLDOMElement_get_attributes(elem, &map);
11156 EXPECT_HR(hr, S_OK);
11157 /* collection dispex test, empty collection */
11158 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11159 EXPECT_HR(hr, S_OK);
11160 did = 0;
11161 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11162 EXPECT_HR(hr, S_OK);
11163 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11164 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11165 EXPECT_HR(hr, S_OK);
11166 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11167 IXMLDOMNamedNodeMap_Release(map);
11168
11169 did = -1;
11170 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
11171 ok(hr == S_OK, "got 0x%08x\n", hr);
11172 ok(did == DISPID_VALUE, "got %d\n", did);
11173
11174 V_VT(&arg) = VT_I4;
11175 V_I4(&arg) = 0;
11176 dispparams.cArgs = 0;
11177 dispparams.cNamedArgs = 0;
11178 dispparams.rgdispidNamedArgs = NULL;
11179 dispparams.rgvarg = &arg;
11180
11181 V_VT(&ret) = VT_EMPTY;
11182 V_DISPATCH(&ret) = (void*)0x1;
11183 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11184 todo_wine {
11185 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11186 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11187 }
11188 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11189
11190 V_VT(&arg) = VT_I4;
11191 V_I4(&arg) = 0;
11192 dispparams.cArgs = 2;
11193 dispparams.cNamedArgs = 0;
11194 dispparams.rgdispidNamedArgs = NULL;
11195 dispparams.rgvarg = &arg;
11196
11197 V_VT(&ret) = VT_EMPTY;
11198 V_DISPATCH(&ret) = (void*)0x1;
11199 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11200 todo_wine {
11201 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11202 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11203 }
11204 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11205
11206 V_VT(&arg) = VT_I4;
11207 V_I4(&arg) = 0;
11208 dispparams.cArgs = 1;
11209 dispparams.cNamedArgs = 0;
11210 dispparams.rgdispidNamedArgs = NULL;
11211 dispparams.rgvarg = &arg;
11212
11213 V_VT(&ret) = VT_EMPTY;
11214 V_DISPATCH(&ret) = (void*)0x1;
11215 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11216 todo_wine
11217 ok(hr == S_OK, "got 0x%08x\n", hr);
11218 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11219 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11220
11221 V_VT(&ret) = VT_EMPTY;
11222 V_DISPATCH(&ret) = (void*)0x1;
11223 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11224 ok(hr == S_OK, "got 0x%08x\n", hr);
11225 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11226 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11227
11228 V_VT(&ret) = VT_EMPTY;
11229 V_DISPATCH(&ret) = (void*)0x1;
11230 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11231 ok(hr == S_OK, "got 0x%08x\n", hr);
11232 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11233 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11234
11235 dispparams.cArgs = 0;
11236 dispparams.cNamedArgs = 0;
11237 dispparams.rgdispidNamedArgs = NULL;
11238 dispparams.rgvarg = NULL;
11239
11240 V_VT(&ret) = VT_EMPTY;
11241 V_I4(&ret) = 1;
11242 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11243 ok(hr == S_OK, "got 0x%08x\n", hr);
11244 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11245 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
11246
11247 dispparams.cArgs = 0;
11248 dispparams.cNamedArgs = 0;
11249 dispparams.rgdispidNamedArgs = NULL;
11250 dispparams.rgvarg = NULL;
11251
11252 V_VT(&ret) = VT_EMPTY;
11253 V_I4(&ret) = 1;
11254 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11255 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11256 todo_wine
11257 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11258 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
11259
11260 IDispatchEx_Release(dispex);
11261 IXMLDOMElement_Release(elem);
11262
11263 /* IXMLDOMImplementation */
11264 hr = IXMLDOMDocument_get_implementation(doc, &impl);
11265 EXPECT_HR(hr, S_OK);
11266
11267 hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11268 EXPECT_HR(hr, S_OK);
11269 IDispatchEx_Release(dispex);
11270 IXMLDOMImplementation_Release(impl);
11271
11272 IXMLDOMDocument_Release(doc);
11273
11274 /* IXMLHTTPRequest */
11275 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11276 &IID_IXMLHttpRequest, (void**)&req);
11277 if (hr == S_OK)
11278 {
11279 hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11280 EXPECT_HR(hr, E_NOINTERFACE);
11281 IXMLHTTPRequest_Release(req);
11282 }
11283
11284 /* IXSLTemplate */
11285 template = create_xsltemplate(&IID_IXSLTemplate);
11286 hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11287 EXPECT_HR(hr, S_OK);
11288 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11289 EXPECT_HR(hr, S_OK);
11290 test_domobj_dispex(unk);
11291 IUnknown_Release(unk);
11292 IDispatchEx_Release(dispex);
11293
11294 /* IXSLProcessor */
11295 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11296 EXPECT_HR(hr, S_OK);
11297 b = VARIANT_FALSE;
11298 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11299 EXPECT_HR(hr, S_OK);
11300 ok(b == VARIANT_TRUE, "got %d\n", b);
11301
11302 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11303 EXPECT_HR(hr, S_OK);
11304 IXMLDOMDocument_Release(doc);
11305
11306 hr = IXSLTemplate_createProcessor(template, &processor);
11307 EXPECT_HR(hr, S_OK);
11308 hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11309 EXPECT_HR(hr, S_OK);
11310 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11311 EXPECT_HR(hr, S_OK);
11312 test_domobj_dispex(unk);
11313 IUnknown_Release(unk);
11314 IDispatchEx_Release(dispex);
11315
11316 IXSLProcessor_Release(processor);
11317 IXSLTemplate_Release(template);
11318
11319 if (is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument))
11320 {
11321 doc = create_document_version(60, &IID_IXMLDOMDocument);
11322 test_domobj_dispex((IUnknown*)doc);
11323 IXMLDOMDocument_Release(doc);
11324 }
11325
11326 free_bstrs();
11327 }
11328
11329 static void test_parseerror(void)
11330 {
11331 IXMLDOMParseError2 *error2;
11332 IXMLDOMParseError *error;
11333 IXMLDOMDocument *doc;
11334 HRESULT hr;
11335
11336 doc = create_document(&IID_IXMLDOMDocument);
11337
11338 hr = IXMLDOMDocument_get_parseError(doc, &error);
11339 EXPECT_HR(hr, S_OK);
11340
11341 hr = IXMLDOMParseError_get_line(error, NULL);
11342 EXPECT_HR(hr, E_INVALIDARG);
11343
11344 hr = IXMLDOMParseError_get_srcText(error, NULL);
11345 EXPECT_HR(hr, E_INVALIDARG);
11346
11347 hr = IXMLDOMParseError_get_linepos(error, NULL);
11348 EXPECT_HR(hr, E_INVALIDARG);
11349
11350 IXMLDOMParseError_Release(error);
11351 IXMLDOMDocument_Release(doc);
11352
11353 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) return;
11354 doc = create_document_version(60, &IID_IXMLDOMDocument);
11355
11356 hr = IXMLDOMDocument_get_parseError(doc, &error);
11357 EXPECT_HR(hr, S_OK);
11358 hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11359 EXPECT_HR(hr, S_OK);
11360 IXMLDOMParseError2_Release(error2);
11361 IXMLDOMParseError_Release(error);
11362 IXMLDOMDocument_Release(doc);
11363 }
11364
11365 static void test_getAttributeNode(void)
11366 {
11367 IXMLDOMAttribute *attr;
11368 IXMLDOMDocument *doc;
11369 IXMLDOMElement *elem;
11370 VARIANT_BOOL v;
11371 HRESULT hr;
11372 BSTR str;
11373
11374 doc = create_document(&IID_IXMLDOMDocument);
11375
11376 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11377 EXPECT_HR(hr, S_OK);
11378
11379 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11380 EXPECT_HR(hr, S_OK);
11381
11382 str = SysAllocString(nonexistent_fileW);
11383 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11384 EXPECT_HR(hr, E_FAIL);
11385
11386 attr = (IXMLDOMAttribute*)0xdeadbeef;
11387 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11388 EXPECT_HR(hr, E_FAIL);
11389 ok(attr == NULL, "got %p\n", attr);
11390 SysFreeString(str);
11391
11392 str = SysAllocString(nonexistent_attrW);
11393 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11394 EXPECT_HR(hr, S_FALSE);
11395
11396 attr = (IXMLDOMAttribute*)0xdeadbeef;
11397 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11398 EXPECT_HR(hr, S_FALSE);
11399 ok(attr == NULL, "got %p\n", attr);
11400 SysFreeString(str);
11401
11402 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11403 EXPECT_HR(hr, S_OK);
11404 IXMLDOMAttribute_Release(attr);
11405
11406 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11407 EXPECT_HR(hr, S_FALSE);
11408
11409 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11410 EXPECT_HR(hr, S_OK);
11411 IXMLDOMAttribute_Release(attr);
11412
11413 IXMLDOMElement_Release(elem);
11414 IXMLDOMDocument_Release(doc);
11415 free_bstrs();
11416 }
11417
11418 static void test_getAttribute(void)
11419 {
11420 IXMLDOMDocument *doc;
11421 IXMLDOMElement *elem;
11422 VARIANT_BOOL v;
11423 VARIANT var;
11424 HRESULT hr;
11425
11426 doc = create_document(&IID_IXMLDOMDocument);
11427
11428 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11429 EXPECT_HR(hr, S_OK);
11430
11431 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11432 EXPECT_HR(hr, S_OK);
11433
11434 VariantInit(&var);
11435 hr = IXMLDOMElement_getAttribute( elem, _bstr_("xmlns:foo"), &var );
11436 EXPECT_HR(hr, S_OK);
11437 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11438 ok( !lstrcmpW(V_BSTR(&var), _bstr_("urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11439 VariantClear(&var);
11440
11441 hr = IXMLDOMElement_getAttribute( elem, _bstr_("a"), &var );
11442 EXPECT_HR(hr, S_OK);
11443 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11444 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr a")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11445 VariantClear(&var);
11446
11447 hr = IXMLDOMElement_getAttribute( elem, _bstr_("foo:b"), &var );
11448 EXPECT_HR(hr, S_OK);
11449 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11450 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr b")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11451 VariantClear(&var);
11452
11453 hr = IXMLDOMElement_getAttribute( elem, _bstr_("b"), &var );
11454 EXPECT_HR(hr, S_FALSE);
11455 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
11456 VariantClear(&var);
11457
11458 hr = IXMLDOMElement_getAttribute( elem, _bstr_("non-existent"), &var );
11459 EXPECT_HR(hr, S_FALSE);
11460 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
11461 VariantClear(&var);
11462
11463 IXMLDOMElement_Release(elem);
11464 IXMLDOMDocument_Release(doc);
11465 free_bstrs();
11466 }
11467
11468 typedef struct {
11469 DOMNodeType type;
11470 const char *name;
11471 REFIID iids[3];
11472 } supporterror_t;
11473
11474 static const supporterror_t supporterror_test[] = {
11475 { NODE_ELEMENT, "element", { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11476 { NODE_ATTRIBUTE, "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11477 { NODE_CDATA_SECTION, "cdata", { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11478 { NODE_ENTITY_REFERENCE, "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11479 { NODE_PROCESSING_INSTRUCTION, "pi", { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11480 { NODE_COMMENT, "comment", { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11481 { NODE_DOCUMENT_FRAGMENT, "fragment", { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11482 { NODE_INVALID }
11483 };
11484
11485 static void test_supporterrorinfo(void)
11486 {
11487 static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11488 &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11489 const supporterror_t *ptr = supporterror_test;
11490 ISupportErrorInfo *errorinfo, *info2;
11491 IXMLDOMSchemaCollection *schemacache;
11492 IXMLDOMNamedNodeMap *map, *map2;
11493 IXMLDOMDocument *doc;
11494 IXMLDOMElement *elem;
11495 VARIANT_BOOL b;
11496 IUnknown *unk;
11497 REFIID *iid;
11498 void *dummy;
11499 HRESULT hr;
11500
11501 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument3)) return;
11502 doc = create_document_version(60, &IID_IXMLDOMDocument3);
11503
11504 EXPECT_REF(doc, 1);
11505 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11506 EXPECT_HR(hr, S_OK);
11507 EXPECT_REF(doc, 1);
11508 ISupportErrorInfo_AddRef(errorinfo);
11509 EXPECT_REF(errorinfo, 2);
11510 EXPECT_REF(doc, 1);
11511 ISupportErrorInfo_Release(errorinfo);
11512
11513 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11514 EXPECT_HR(hr, S_OK);
11515 ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11516
11517 /* error interface can't be queried back for DOM interface */
11518 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11519 EXPECT_HR(hr, E_NOINTERFACE);
11520 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11521 EXPECT_HR(hr, E_NOINTERFACE);
11522
11523 ISupportErrorInfo_Release(info2);
11524
11525 iid = iids;
11526 while (*iid)
11527 {
11528 hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11529 EXPECT_HR(hr, S_OK);
11530 if (hr == S_OK)
11531 {
11532 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11533 ok(hr == S_OK, "got 0x%08x for %s\n", hr, wine_dbgstr_guid(*iid));
11534 IUnknown_Release(unk);
11535 }
11536
11537 iid++;
11538 }
11539
11540 ISupportErrorInfo_Release(errorinfo);
11541
11542 while (ptr->type != NODE_INVALID)
11543 {
11544 IXMLDOMNode *node;
11545 VARIANT type;
11546
11547 V_VT(&type) = VT_I1;
11548 V_I1(&type) = ptr->type;
11549
11550 hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11551 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11552
11553 EXPECT_REF(node, 1);
11554 hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11555 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11556 EXPECT_REF(node, 1);
11557
11558 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11559 ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11560
11561 iid = ptr->iids;
11562
11563 while (*iid)
11564 {
11565 hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11566 if (hr == S_OK)
11567 {
11568 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11569 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, wine_dbgstr_guid(*iid));
11570 IUnknown_Release(unk);
11571 }
11572
11573 iid++;
11574 }
11575
11576 ISupportErrorInfo_Release(errorinfo);
11577 IXMLDOMNode_Release(node);
11578 ptr++;
11579 }
11580
11581 /* IXMLDOMNamedNodeMap */
11582 b = VARIANT_FALSE;
11583 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11584 EXPECT_HR(hr, S_OK);
11585 ok(b == VARIANT_TRUE, "got %d\n", b);
11586
11587 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11588 EXPECT_HR(hr, S_OK);
11589
11590 hr = IXMLDOMElement_get_attributes(elem, &map);
11591 EXPECT_HR(hr, S_OK);
11592
11593 EXPECT_REF(map, 1);
11594 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11595 EXPECT_HR(hr, S_OK);
11596 EXPECT_REF(map, 2);
11597
11598 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11599 EXPECT_HR(hr, S_OK);
11600
11601 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11602 EXPECT_HR(hr, S_OK);
11603 ok(map == map2, "got %p\n", map2);
11604 IXMLDOMNamedNodeMap_Release(map2);
11605
11606 EXPECT_REF(errorinfo, 2);
11607 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11608 EXPECT_HR(hr, S_OK);
11609 EXPECT_REF(errorinfo, 3);
11610 EXPECT_REF(map, 3);
11611 IUnknown_Release(unk);
11612
11613 ISupportErrorInfo_Release(errorinfo);
11614 IXMLDOMNamedNodeMap_Release(map);
11615 IXMLDOMElement_Release(elem);
11616
11617 IXMLDOMDocument_Release(doc);
11618
11619 /* IXMLDOMSchemaCollection */
11620 hr = CoCreateInstance(&CLSID_XMLSchemaCache, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (void**)&schemacache);
11621 ok(hr == S_OK, "failed to create schema collection, 0x%08x\n", hr);
11622
11623 hr = IXMLDOMSchemaCollection_QueryInterface(schemacache, &IID_ISupportErrorInfo, (void**)&errorinfo);
11624 ok(hr == S_OK, "got 0x%08x\n", hr);
11625
11626 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMSchemaCollection);
11627 ok(hr == S_OK, "got 0x%08x\n", hr);
11628
11629 ISupportErrorInfo_Release(errorinfo);
11630 IXMLDOMSchemaCollection_Release(schemacache);
11631
11632 free_bstrs();
11633 }
11634
11635 typedef struct {
11636 DOMNodeType type;
11637 const char *name;
11638 const char *put_content;
11639 HRESULT put_hr;
11640 VARTYPE get_vt;
11641 HRESULT get_hr;
11642 } node_value_t;
11643
11644 static const node_value_t nodevalue_test[] = {
11645 { NODE_ELEMENT, "element", "", E_FAIL, VT_NULL, S_FALSE },
11646 { NODE_ATTRIBUTE, "attr", "value", S_OK, VT_BSTR, S_OK },
11647 { NODE_TEXT, "text", "textdata", S_OK, VT_BSTR, S_OK },
11648 { NODE_CDATA_SECTION , "cdata", "cdata data", S_OK, VT_BSTR, S_OK },
11649 { NODE_ENTITY_REFERENCE, "entityref", "ref", E_FAIL, VT_NULL, S_FALSE },
11650 { NODE_PROCESSING_INSTRUCTION, "pi", "instr", S_OK, VT_BSTR, S_OK },
11651 { NODE_COMMENT, "comment", "comment data", S_OK, VT_BSTR, S_OK },
11652 { NODE_DOCUMENT_FRAGMENT, "docfrag", "", E_FAIL, VT_NULL, S_FALSE },
11653 { NODE_INVALID }
11654 };
11655
11656 static void test_nodeValue(void)
11657 {
11658 const node_value_t *ptr = nodevalue_test;
11659 IXMLDOMDocument *doc;
11660 HRESULT hr;
11661
11662 doc = create_document(&IID_IXMLDOMDocument);
11663
11664 while (ptr->type != NODE_INVALID)
11665 {
11666 IXMLDOMNode *node;
11667 VARIANT v;
11668
11669 V_VT(&v) = VT_I2;
11670 V_I2(&v) = ptr->type;
11671
11672 hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11673 ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11674
11675 hr = IXMLDOMNode_get_nodeValue(node, NULL);
11676 ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11677
11678 V_VT(&v) = VT_BSTR;
11679 V_BSTR(&v) = _bstr_(ptr->put_content);
11680 hr = IXMLDOMNode_put_nodeValue(node, v);
11681 ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11682
11683 V_VT(&v) = VT_EMPTY;
11684 hr = IXMLDOMNode_get_nodeValue(node, &v);
11685 ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11686 ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11687 if (hr == S_OK)
11688 ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11689 wine_dbgstr_w(V_BSTR(&v)));
11690 VariantClear(&v);
11691
11692 IXMLDOMNode_Release(node);
11693
11694 ptr++;
11695 }
11696
11697 IXMLDOMDocument_Release(doc);
11698 }
11699
11700 static void test_xmlns_attribute(void)
11701 {
11702 BSTR str;
11703 IXMLDOMDocument *doc;
11704 IXMLDOMElement *root;
11705 IXMLDOMAttribute *pAttribute;
11706 IXMLDOMElement *elem;
11707 HRESULT hr;
11708 VARIANT v;
11709
11710 doc = create_document(&IID_IXMLDOMDocument);
11711
11712 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
11713 EXPECT_HR(hr, S_OK);
11714
11715 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
11716 EXPECT_HR(hr, S_OK);
11717
11718 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("xmlns:dt"), &pAttribute);
11719 ok( hr == S_OK, "returns %08x\n", hr );
11720
11721 V_VT(&v) = VT_BSTR;
11722 V_BSTR(&v) = _bstr_("urn:schemas-microsoft-com:datatypes");
11723 hr = IXMLDOMAttribute_put_nodeValue(pAttribute, v);
11724 ok(hr == S_OK, "ret %08x\n", hr );
11725
11726 hr = IXMLDOMElement_setAttributeNode(root, pAttribute, NULL);
11727 ok(hr == S_OK, "ret %08x\n", hr );
11728
11729 hr = IXMLDOMNode_put_dataType((IXMLDOMNode*)root, _bstr_("bin.base64"));
11730 ok(hr == S_OK, "ret %08x\n", hr );
11731
11732 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11733 EXPECT_HR(hr, S_OK);
11734
11735 str = NULL;
11736 hr = IXMLDOMElement_get_xml(elem, &str);
11737 ok( hr == S_OK, "got 0x%08x\n", hr);
11738 todo_wine ok( lstrcmpW(str, _bstr_("<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>")) == 0,
11739 "got %s\n", wine_dbgstr_w(str));
11740 SysFreeString(str);
11741
11742 IXMLDOMElement_Release(elem);
11743 IXMLDOMAttribute_Release( pAttribute);
11744
11745 IXMLDOMDocument_Release(doc);
11746
11747 free_bstrs();
11748 }
11749
11750 static const char namespacesA[] =
11751 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11752 " <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11753 " <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11754 " <ns1:elem3/>"
11755 " <ns1:elem4/>"
11756 " <elem5 xmlns=\"http://blahblah.org\"/>"
11757 " <ns1:elem6>true</ns1:elem6>"
11758 " </ns1:elem1>";
11759
11760 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11761 static const char xsd_schema1_xml[] =
11762 "<?xml version='1.0'?>"
11763 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11764 " targetNamespace='x-schema:test1.xsd'>"
11765 " <element name='root'>"
11766 " <complexType>"
11767 " <sequence maxOccurs='unbounded'>"
11768 " <any/>"
11769 " </sequence>"
11770 " </complexType>"
11771 " </element>"
11772 "</schema>";
11773
11774 static void test_get_namespaces(void)
11775 {
11776 IXMLDOMSchemaCollection *collection, *collection2;
11777 IXMLDOMDocument2 *doc, *doc2;
11778 IEnumVARIANT *enumv, *enum2;
11779 IUnknown *unk1, *unk2;
11780 IXMLDOMNode *node;
11781 VARIANT_BOOL b;
11782 HRESULT hr;
11783 VARIANT v;
11784 LONG len;
11785 BSTR s;
11786
11787 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
11788 doc = create_document(&IID_IXMLDOMDocument2);
11789
11790 /* null pointer */
11791 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11792 EXPECT_HR(hr, E_POINTER);
11793
11794 /* no document loaded */
11795 collection = (void*)0xdeadbeef;
11796 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11797 EXPECT_HR(hr, S_OK);
11798 if (hr != S_OK)
11799 {
11800 IXMLDOMDocument2_Release(doc);
11801 return;
11802 }
11803 EXPECT_REF(collection, 2);
11804
11805 collection2 = (void*)0xdeadbeef;
11806 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11807 EXPECT_HR(hr, S_OK);
11808 ok(collection == collection2, "got %p\n", collection2);
11809 EXPECT_REF(collection, 3);
11810 IXMLDOMSchemaCollection_Release(collection);
11811
11812 len = -1;
11813 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11814 EXPECT_HR(hr, S_OK);
11815 ok(len == 0, "got %d\n", len);
11816 IXMLDOMSchemaCollection_Release(collection);
11817
11818 /* now with document */
11819 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11820 EXPECT_HR(hr, S_OK);
11821
11822 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11823 EXPECT_HR(hr, S_OK);
11824
11825 len = -1;
11826 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11827 EXPECT_HR(hr, S_OK);
11828 ok(len == 2, "got %d\n", len);
11829
11830 /* try to lookup some uris */
11831 node = (void*)0xdeadbeef;
11832 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11833 EXPECT_HR(hr, S_OK);
11834 ok(node == NULL, "got %p\n", node);
11835
11836 node = (void*)0xdeadbeef;
11837 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11838 EXPECT_HR(hr, S_OK);
11839 ok(node == NULL, "got %p\n", node);
11840
11841 /* load schema and try to add it */
11842 doc2 = create_document(&IID_IXMLDOMDocument2);
11843 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11844 EXPECT_HR(hr, S_OK);
11845
11846 V_VT(&v) = VT_DISPATCH;
11847 V_DISPATCH(&v) = (IDispatch*)doc2;
11848 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11849 EXPECT_HR(hr, E_FAIL);
11850
11851 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11852 EXPECT_HR(hr, S_OK);
11853 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11854 SysFreeString(s);
11855
11856 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11857 EXPECT_HR(hr, S_OK);
11858 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11859 SysFreeString(s);
11860
11861 s = (void*)0xdeadbeef;
11862 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11863 EXPECT_HR(hr, E_FAIL);
11864 ok(s == (void*)0xdeadbeef, "got %p\n", s);
11865
11866 /* enumerate */
11867 enumv = (void*)0xdeadbeef;
11868 EXPECT_REF(collection, 2);
11869 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11870 EXPECT_HR(hr, S_OK);
11871 EXPECT_REF(collection, 3);
11872 ok(enumv != NULL, "got %p\n", enumv);
11873
11874 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IUnknown, (void**)&unk1);
11875 EXPECT_HR(hr, S_OK);
11876 hr = IEnumVARIANT_QueryInterface(enumv, &IID_IUnknown, (void**)&unk2);
11877 EXPECT_HR(hr, S_OK);
11878 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
11879 IUnknown_Release(unk1);
11880 IUnknown_Release(unk2);
11881
11882 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2);
11883 EXPECT_HR(hr, E_NOINTERFACE);
11884
11885 V_VT(&v) = VT_EMPTY;
11886 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11887 EXPECT_HR(hr, S_OK);
11888 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11889 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11890 VariantClear(&v);
11891
11892 V_VT(&v) = VT_EMPTY;
11893 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11894 EXPECT_HR(hr, S_OK);
11895 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11896 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11897 VariantClear(&v);
11898
11899 V_VT(&v) = VT_NULL;
11900 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11901 EXPECT_HR(hr, S_FALSE);
11902 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11903
11904 IEnumVARIANT_Release(enumv);
11905 IXMLDOMSchemaCollection_Release(collection);
11906
11907 IXMLDOMDocument2_Release(doc);
11908
11909 /* now with CLSID_DOMDocument60 */
11910 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) return;
11911 doc = create_document_version(60, &IID_IXMLDOMDocument2);
11912
11913 /* null pointer */
11914 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11915 EXPECT_HR(hr, E_POINTER);
11916
11917 /* no document loaded */
11918 collection = (void*)0xdeadbeef;
11919 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11920 EXPECT_HR(hr, S_OK);
11921 if (hr != S_OK)
11922 {
11923 IXMLDOMDocument2_Release(doc);
11924 return;
11925 }
11926 EXPECT_REF(collection, 2);
11927
11928 collection2 = (void*)0xdeadbeef;
11929 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11930 EXPECT_HR(hr, S_OK);
11931 ok(collection == collection2, "got %p\n", collection2);
11932 EXPECT_REF(collection, 3);
11933 IXMLDOMSchemaCollection_Release(collection);
11934
11935 len = -1;
11936 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11937 EXPECT_HR(hr, S_OK);
11938 ok(len == 0, "got %d\n", len);
11939 IXMLDOMSchemaCollection_Release(collection);
11940
11941 /* now with document */
11942 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11943 EXPECT_HR(hr, S_OK);
11944
11945 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11946 EXPECT_HR(hr, S_OK);
11947
11948 len = -1;
11949 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11950 EXPECT_HR(hr, S_OK);
11951 ok(len == 2, "got %d\n", len);
11952
11953 /* try to lookup some uris */
11954 node = (void*)0xdeadbeef;
11955 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11956 EXPECT_HR(hr, E_NOTIMPL);
11957 ok(broken(node == (void*)0xdeadbeef) || (node == NULL), "got %p\n", node);
11958
11959 /* load schema and try to add it */
11960 doc2 = create_document(&IID_IXMLDOMDocument2);
11961 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11962 EXPECT_HR(hr, S_OK);
11963
11964 V_VT(&v) = VT_DISPATCH;
11965 V_DISPATCH(&v) = (IDispatch*)doc2;
11966 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11967 EXPECT_HR(hr, E_FAIL);
11968 IXMLDOMDocument2_Release(doc2);
11969
11970 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11971 EXPECT_HR(hr, S_OK);
11972 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11973 SysFreeString(s);
11974
11975 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11976 EXPECT_HR(hr, S_OK);
11977 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11978 SysFreeString(s);
11979
11980 s = (void*)0xdeadbeef;
11981 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11982 EXPECT_HR(hr, E_FAIL);
11983 ok(broken(s == (void*)0xdeadbeef) || (s == NULL), "got %p\n", s);
11984
11985 /* enumerate */
11986 enumv = (void*)0xdeadbeef;
11987 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11988 EXPECT_HR(hr, S_OK);
11989 ok(enumv != NULL, "got %p\n", enumv);
11990
11991 V_VT(&v) = VT_EMPTY;
11992 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11993 EXPECT_HR(hr, S_OK);
11994 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11995 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11996 VariantClear(&v);
11997
11998 V_VT(&v) = VT_EMPTY;
11999 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12000 EXPECT_HR(hr, S_OK);
12001 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
12002 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
12003 VariantClear(&v);
12004
12005 V_VT(&v) = VT_NULL;
12006 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
12007 EXPECT_HR(hr, S_FALSE);
12008 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
12009
12010 IEnumVARIANT_Release(enumv);
12011 IXMLDOMSchemaCollection_Release(collection);
12012 IXMLDOMDocument2_Release(doc);
12013 free_bstrs();
12014 }
12015
12016 static const DOMNodeType put_data_types[] = {
12017 NODE_TEXT,
12018 NODE_CDATA_SECTION,
12019 NODE_PROCESSING_INSTRUCTION,
12020 NODE_COMMENT,
12021 NODE_INVALID
12022 };
12023
12024 static void test_put_data(void)
12025 {
12026 static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0};
12027 WCHAR buff[100], *data;
12028 IXMLDOMDocument *doc;
12029 const DOMNodeType *type;
12030 IXMLDOMText *text;
12031 IXMLDOMNode *node;
12032 VARIANT v;
12033 BSTR get_data;
12034 HRESULT hr;
12035
12036 doc = create_document(&IID_IXMLDOMDocument);
12037
12038 memcpy(&buff[2], test_data, sizeof(test_data));
12039 /* just a big length */
12040 *(DWORD*)buff = 0xf0f0;
12041 data = &buff[2];
12042
12043 type = put_data_types;
12044 while (*type != NODE_INVALID)
12045 {
12046 V_VT(&v) = VT_I2;
12047 V_I2(&v) = *type;
12048
12049 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12050 EXPECT_HR(hr, S_OK);
12051
12052 /* put_data() is interface-specific */
12053 switch (*type)
12054 {
12055 case NODE_TEXT:
12056 {
12057 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12058 EXPECT_HR(hr, S_OK);
12059 hr = IXMLDOMText_put_data(text, data);
12060 EXPECT_HR(hr, S_OK);
12061
12062 hr = IXMLDOMText_get_data(text, &get_data);
12063 EXPECT_HR(hr, S_OK);
12064
12065 IXMLDOMText_Release(text);
12066 break;
12067 }
12068 case NODE_CDATA_SECTION:
12069 {
12070 IXMLDOMCDATASection *cdata;
12071
12072 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
12073 EXPECT_HR(hr, S_OK);
12074 hr = IXMLDOMCDATASection_put_data(cdata, data);
12075 EXPECT_HR(hr, S_OK);
12076
12077 hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
12078 EXPECT_HR(hr, S_OK);
12079
12080 IXMLDOMCDATASection_Release(cdata);
12081 break;
12082 }
12083 case NODE_PROCESSING_INSTRUCTION:
12084 {
12085 IXMLDOMProcessingInstruction *pi;
12086
12087 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
12088 EXPECT_HR(hr, S_OK);
12089 hr = IXMLDOMProcessingInstruction_put_data(pi, data);
12090 EXPECT_HR(hr, S_OK);
12091
12092 hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
12093 EXPECT_HR(hr, S_OK);
12094
12095 IXMLDOMProcessingInstruction_Release(pi);
12096 break;
12097 }
12098 case NODE_COMMENT:
12099 {
12100 IXMLDOMComment *comment;
12101
12102 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
12103 EXPECT_HR(hr, S_OK);
12104 hr = IXMLDOMComment_put_data(comment, data);
12105 EXPECT_HR(hr, S_OK);
12106
12107 hr = IXMLDOMComment_get_data(comment, &get_data);
12108 EXPECT_HR(hr, S_OK);
12109
12110 IXMLDOMComment_Release(comment);
12111 break;
12112 }
12113 default:
12114 get_data = NULL;
12115 break;
12116 }
12117
12118 /* compare */
12119 ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
12120 wine_dbgstr_w(data));
12121 SysFreeString(get_data);
12122
12123 IXMLDOMNode_Release(node);
12124 type++;
12125 }
12126
12127 /* \r\n sequence is never escaped */
12128 V_VT(&v) = VT_I2;
12129 V_I2(&v) = NODE_TEXT;
12130
12131 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12132 ok(hr == S_OK, "got 0x%08x\n", hr);
12133
12134 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12135
12136 hr = IXMLDOMText_put_data(text, _bstr_("\r\n"));
12137 ok(hr == S_OK, "got 0x%08x\n", hr);
12138
12139 hr = IXMLDOMText_get_data(text, &get_data);
12140 ok(hr == S_OK, "got 0x%08x\n", hr);
12141 todo_wine
12142 ok(!lstrcmpW(get_data, _bstr_("\n")), "got %s\n", wine_dbgstr_w(get_data));
12143 SysFreeString(get_data);
12144
12145 hr = IXMLDOMText_get_xml(text, &get_data);
12146 ok(hr == S_OK, "got 0x%08x\n", hr);
12147 ok(!lstrcmpW(get_data, _bstr_("\r\n")), "got %s\n", wine_dbgstr_w(get_data));
12148 SysFreeString(get_data);
12149
12150 IXMLDOMText_Release(text);
12151 IXMLDOMNode_Release(node);
12152
12153 IXMLDOMDocument_Release(doc);
12154 free_bstrs();
12155 }
12156
12157 static void test_putref_schemas(void)
12158 {
12159 IXMLDOMSchemaCollection *cache;
12160 IXMLDOMDocument2 *doc;
12161 VARIANT schema;
12162 HRESULT hr;
12163
12164 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
12165 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
12166
12167 doc = create_document(&IID_IXMLDOMDocument2);
12168 cache = create_cache(&IID_IXMLDOMSchemaCollection);
12169
12170 /* set to NULL iface when no schema is set */
12171 V_VT(&schema) = VT_DISPATCH;
12172 V_DISPATCH(&schema) = NULL;
12173 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12174 EXPECT_HR(hr, S_OK);
12175
12176 V_VT(&schema) = VT_UNKNOWN;
12177 V_UNKNOWN(&schema) = NULL;
12178 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12179 EXPECT_HR(hr, S_OK);
12180
12181 /* set as VT_DISPATCH, reset with it */
12182 V_VT(&schema) = VT_DISPATCH;
12183 V_DISPATCH(&schema) = (IDispatch*)cache;
12184 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12185 EXPECT_HR(hr, S_OK);
12186
12187 V_DISPATCH(&schema) = NULL;
12188 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12189 EXPECT_HR(hr, S_OK);
12190 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12191
12192 V_VT(&schema) = VT_DISPATCH;
12193 V_DISPATCH(&schema) = NULL;
12194 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12195 EXPECT_HR(hr, S_OK);
12196
12197 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12198 V_VT(&schema) = VT_I2;
12199 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12200 EXPECT_HR(hr, S_FALSE);
12201 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12202 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12203
12204 /* set as VT_UNKNOWN, reset with it */
12205 V_VT(&schema) = VT_UNKNOWN;
12206 V_UNKNOWN(&schema) = (IUnknown*)cache;
12207 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12208 EXPECT_HR(hr, S_OK);
12209
12210 V_DISPATCH(&schema) = NULL;
12211 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12212 EXPECT_HR(hr, S_OK);
12213 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12214
12215 V_VT(&schema) = VT_UNKNOWN;
12216 V_UNKNOWN(&schema) = NULL;
12217 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12218 EXPECT_HR(hr, S_OK);
12219
12220 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12221 V_VT(&schema) = VT_I2;
12222 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12223 EXPECT_HR(hr, S_FALSE);
12224 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12225 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12226
12227 IXMLDOMSchemaCollection_Release(cache);
12228 IXMLDOMDocument2_Release(doc);
12229 }
12230
12231 static void test_namedmap_newenum(void)
12232 {
12233 IEnumVARIANT *enum1, *enum2, *enum3;
12234 IXMLDOMNamedNodeMap *map;
12235 IUnknown *unk1, *unk2;
12236 IXMLDOMDocument *doc;
12237 IXMLDOMElement *elem;
12238 IXMLDOMNode *node;
12239 VARIANT_BOOL b;
12240 HRESULT hr;
12241 VARIANT v;
12242 BSTR str;
12243
12244 doc = create_document(&IID_IXMLDOMDocument);
12245
12246 hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b);
12247 EXPECT_HR(hr, S_OK);
12248
12249 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12250 EXPECT_HR(hr, S_OK);
12251
12252 hr = IXMLDOMElement_get_attributes(elem, &map);
12253 EXPECT_HR(hr, S_OK);
12254 IXMLDOMElement_Release(elem);
12255
12256 enum1 = NULL;
12257 EXPECT_REF(map, 1);
12258 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1);
12259 EXPECT_HR(hr, S_OK);
12260 ok(enum1 != NULL, "got %p\n", enum1);
12261 EXPECT_REF(map, 1);
12262 EXPECT_REF(enum1, 2);
12263
12264 enum2 = NULL;
12265 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2);
12266 EXPECT_HR(hr, S_OK);
12267 ok(enum2 == enum1, "got %p\n", enum2);
12268
12269 IEnumVARIANT_Release(enum2);
12270
12271 EXPECT_REF(map, 1);
12272 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2);
12273 EXPECT_HR(hr, S_OK);
12274 EXPECT_REF(map, 2);
12275 EXPECT_REF(enum2, 1);
12276 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
12277
12278 IEnumVARIANT_Release(enum1);
12279
12280 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
12281 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1);
12282 EXPECT_HR(hr, S_OK);
12283 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
12284 EXPECT_HR(hr, S_OK);
12285 EXPECT_REF(map, 3);
12286 EXPECT_REF(enum2, 2);
12287 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
12288 IUnknown_Release(unk1);
12289 IUnknown_Release(unk2);
12290
12291 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3);
12292 EXPECT_HR(hr, S_OK);
12293 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
12294 IEnumVARIANT_Release(enum3);
12295
12296 /* iteration tests */
12297 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
12298 EXPECT_HR(hr, S_OK);
12299 hr = IXMLDOMNode_get_nodeName(node, &str);
12300 EXPECT_HR(hr, S_OK);
12301 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12302 SysFreeString(str);
12303 IXMLDOMNode_Release(node);
12304
12305 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12306 EXPECT_HR(hr, S_OK);
12307 hr = IXMLDOMNode_get_nodeName(node, &str);
12308 EXPECT_HR(hr, S_OK);
12309 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12310 SysFreeString(str);
12311 IXMLDOMNode_Release(node);
12312
12313 V_VT(&v) = VT_EMPTY;
12314 hr = IEnumVARIANT_Next(enum2, 1, &v, NULL);
12315 EXPECT_HR(hr, S_OK);
12316 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
12317 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
12318 EXPECT_HR(hr, S_OK);
12319 hr = IXMLDOMNode_get_nodeName(node, &str);
12320 EXPECT_HR(hr, S_OK);
12321 ok(!lstrcmpW(str, _bstr_("attr1")), "got node name %s\n", wine_dbgstr_w(str));
12322 SysFreeString(str);
12323 IXMLDOMNode_Release(node);
12324 VariantClear(&v);
12325
12326 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12327 EXPECT_HR(hr, S_OK);
12328 hr = IXMLDOMNode_get_nodeName(node, &str);
12329 EXPECT_HR(hr, S_OK);
12330 ok(!lstrcmpW(str, _bstr_("attr2")), "got %s\n", wine_dbgstr_w(str));
12331 SysFreeString(str);
12332 IXMLDOMNode_Release(node);
12333
12334 IEnumVARIANT_Release(enum2);
12335 IXMLDOMNamedNodeMap_Release(map);
12336 IXMLDOMDocument_Release(doc);
12337 }
12338
12339 static const char xsltext_xsl[] =
12340 "<?xml version=\"1.0\"?>"
12341 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
12342 "<xsl:output method=\"html\" encoding=\"us-ascii\"/>"
12343 "<xsl:template match=\"/\">"
12344 " <xsl:choose>"
12345 " <xsl:when test=\"testkey\">"
12346 " <xsl:text>testdata</xsl:text>"
12347 " </xsl:when>"
12348 " </xsl:choose>"
12349 "</xsl:template>"
12350 "</xsl:stylesheet>";
12351
12352 static const char omitxmldecl_xsl[] =
12353 "<?xml version=\"1.0\"?>"
12354 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
12355 "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>"
12356 "<xsl:template match=\"/\">"
12357 " <xsl:for-each select=\"/a/item\">"
12358 " <xsl:element name=\"node\">"
12359 " <xsl:value-of select=\"@name\"/>"
12360 " </xsl:element>"
12361 " </xsl:for-each>"
12362 "</xsl:template>"
12363 "</xsl:stylesheet>";
12364
12365 static const char omitxmldecl_doc[] =
12366 "<?xml version=\"1.0\"?>"
12367 "<a>"
12368 " <item name=\"item1\"/>"
12369 " <item name=\"item2\"/>"
12370 "</a>";
12371
12372 static void test_xsltext(void)
12373 {
12374 IXMLDOMDocument *doc, *doc2;
12375 VARIANT_BOOL b;
12376 HRESULT hr;
12377 BSTR ret;
12378
12379 doc = create_document(&IID_IXMLDOMDocument);
12380 doc2 = create_document(&IID_IXMLDOMDocument);
12381
12382 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
12383 EXPECT_HR(hr, S_OK);
12384
12385 hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b);
12386 EXPECT_HR(hr, S_OK);
12387
12388 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
12389 EXPECT_HR(hr, S_OK);
12390 ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret));
12391 SysFreeString(ret);
12392
12393 /* omit-xml-declaration */
12394 hr = IXMLDOMDocument_loadXML(doc, _bstr_(omitxmldecl_xsl), &b);
12395 ok(hr == S_OK, "got 0x%08x\n", hr);
12396 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(omitxmldecl_doc), &b);
12397 ok(hr == S_OK, "got 0x%08x\n", hr);
12398
12399 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
12400 ok(hr == S_OK, "got 0x%08x\n", hr);
12401 ok(!lstrcmpW(ret, _bstr_("<node>item1</node><node>item2</node>")), "transform result %s\n", wine_dbgstr_w(ret));
12402 SysFreeString(ret);
12403
12404 IXMLDOMDocument_Release(doc2);
12405 IXMLDOMDocument_Release(doc);
12406 free_bstrs();
12407 }
12408
12409 struct attrtest_t {
12410 const char *name;
12411 const char *uri;
12412 const char *prefix;
12413 const char *href;
12414 };
12415
12416 static struct attrtest_t attrtests[] = {
12417 { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" },
12418 { "xmlns", "nondefaulturi", "xmlns", "xmlns" },
12419 { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" },
12420 { "c", "nsref1", NULL, "nsref1" },
12421 { "ns:c", "nsref1", "ns", "nsref1" },
12422 { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" },
12423 { "xmlns:c", "nondefaulturi", "xmlns", "" },
12424 { 0 }
12425 };
12426
12427 static void test_create_attribute(void)
12428 {
12429 struct attrtest_t *ptr = attrtests;
12430 IXMLDOMElement *el;
12431 IXMLDOMDocument *doc;
12432 IXMLDOMNode *node, *node2;
12433 VARIANT var;
12434 HRESULT hr;
12435 int i = 0;
12436 BSTR str;
12437
12438 doc = create_document(&IID_IXMLDOMDocument);
12439
12440 while (ptr->name)
12441 {
12442 V_VT(&var) = VT_I1;
12443 V_I1(&var) = NODE_ATTRIBUTE;
12444 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
12445 ok(hr == S_OK, "got 0x%08x\n", hr);
12446
12447 str = NULL;
12448 hr = IXMLDOMNode_get_prefix(node, &str);
12449 if (ptr->prefix)
12450 {
12451 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
12452 ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix);
12453 }
12454 else
12455 {
12456 ok(hr == S_FALSE, "%d: got 0x%08x\n", i, hr);
12457 ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str));
12458 }
12459 SysFreeString(str);
12460
12461 str = NULL;
12462 hr = IXMLDOMNode_get_namespaceURI(node, &str);
12463 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
12464 ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href);
12465 SysFreeString(str);
12466
12467 IXMLDOMNode_Release(node);
12468 free_bstrs();
12469
12470 i++;
12471 ptr++;
12472 }
12473
12474 V_VT(&var) = VT_I1;
12475 V_I1(&var) = NODE_ELEMENT;
12476 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2);
12477 ok(hr == S_OK, "got 0x%08x\n", hr);
12478
12479 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el);
12480 ok(hr == S_OK, "got 0x%08x\n", hr);
12481 IXMLDOMNode_Release(node2);
12482
12483 V_VT(&var) = VT_I1;
12484 V_I1(&var) = NODE_ATTRIBUTE;
12485 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node);
12486 ok(hr == S_OK, "got 0x%08x\n", hr);
12487
12488 hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL);
12489 ok(hr == S_OK, "got 0x%08x\n", hr);
12490
12491 /* for some reason default namespace uri is not reported */
12492 hr = IXMLDOMNode_get_namespaceURI(node, &str);
12493 ok(hr == S_OK, "got 0x%08x\n", hr);
12494 ok(!lstrcmpW(str, _bstr_("")), "got uri %s\n", wine_dbgstr_w(str));
12495 SysFreeString(str);
12496
12497 IXMLDOMNode_Release(node);
12498 IXMLDOMElement_Release(el);
12499 IXMLDOMDocument_Release(doc);
12500 free_bstrs();
12501 }
12502
12503 static void test_url(void)
12504 {
12505 IXMLDOMDocument *doc;
12506 HRESULT hr;
12507 BSTR s;
12508
12509 doc = create_document(&IID_IXMLDOMDocument);
12510
12511 hr = IXMLDOMDocument_get_url(doc, NULL);
12512 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
12513
12514 s = (void *)0xdeadbeef;
12515 hr = IXMLDOMDocument_get_url(doc, &s);
12516 ok(hr == S_FALSE, "got 0x%08x\n", hr);
12517 ok(s == NULL, "got %s\n", wine_dbgstr_w(s));
12518
12519 IXMLDOMDocument_Release(doc);
12520 }
12521
12522 static void test_merging_text(void)
12523 {
12524 IXMLDOMText *nodetext;
12525 IXMLDOMText *newtext;
12526 IXMLDOMElement *root;
12527 IXMLDOMDocument *doc;
12528 IXMLDOMNode *first;
12529 HRESULT hr;
12530 VARIANT v;
12531 BSTR str;
12532 int i;
12533
12534 doc = create_document(&IID_IXMLDOMDocument);
12535
12536 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
12537 EXPECT_HR(hr, S_OK);
12538
12539 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
12540 EXPECT_HR(hr, S_OK);
12541
12542 /* test xmlAddChild */
12543 for (i = 0; i < 10; i++)
12544 {
12545 str = SysAllocString(szstr1);
12546 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
12547 SysFreeString(str);
12548 EXPECT_HR(hr, S_OK);
12549
12550 newtext = NULL;
12551 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)nodetext, (IXMLDOMNode**)&newtext);
12552 EXPECT_HR(hr, S_OK);
12553 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
12554
12555 IXMLDOMText_Release(newtext);
12556 IXMLDOMText_Release(nodetext);
12557 }
12558
12559 /* test xmlAddPrevSibling */
12560 hr = IXMLDOMElement_get_firstChild(root, &first);
12561 EXPECT_HR(hr, S_OK);
12562 V_VT(&v) = VT_UNKNOWN;
12563 V_UNKNOWN(&v) = (IUnknown*)first;
12564 for (i = 0; i < 10; i++)
12565 {
12566 str = SysAllocString(szstr2);
12567 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
12568 SysFreeString(str);
12569 EXPECT_HR(hr, S_OK);
12570
12571 newtext = NULL;
12572 hr = IXMLDOMElement_insertBefore(root, (IXMLDOMNode*)nodetext, v, (IXMLDOMNode**)&newtext);
12573 EXPECT_HR(hr, S_OK);
12574 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
12575
12576 IXMLDOMText_Release(newtext);
12577 IXMLDOMText_Release(nodetext);
12578 }
12579
12580 IXMLDOMNode_Release(first);
12581 IXMLDOMElement_Release(root);
12582 IXMLDOMDocument_Release(doc);
12583
12584 free_bstrs();
12585 }
12586
12587 static HRESULT WINAPI transformdest_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
12588 {
12589 BOOL known_iid = IsEqualIID(riid, &IID_IHTMLObjectElement) ||
12590 IsEqualIID(riid, &IID_transformdest_unknown) ||
12591 IsEqualIID(riid, &IID_IServiceProvider) ||
12592 IsEqualIID(riid, &IID_IStream) ||
12593 IsEqualIID(riid, &IID_ISequentialStream) ||
12594 IsEqualIID(riid, &IID_IRequestDictionary);
12595
12596 todo_wine_if(IsEqualIID(riid, &IID_IXMLDOMDocument))
12597 ok(known_iid, "Unexpected riid %s\n", wine_dbgstr_guid(riid));
12598
12599 return E_NOINTERFACE;
12600 }
12601
12602 static ULONG WINAPI transformdest_AddRef(IUnknown *iface)
12603 {
12604 return 2;
12605 }
12606
12607 static ULONG WINAPI transformdest_Release(IUnknown *iface)
12608 {
12609 return 1;
12610 }
12611
12612 static const IUnknownVtbl transformdestvtbl =
12613 {
12614 transformdest_QueryInterface,
12615 transformdest_AddRef,
12616 transformdest_Release,
12617 };
12618
12619 static void test_transformNodeToObject(void)
12620 {
12621 IUnknown transformdest = { &transformdestvtbl };
12622 IXMLDOMDocument *doc, *doc2, *doc3;
12623 VARIANT_BOOL b;
12624 HRESULT hr;
12625 VARIANT v;
12626
12627 doc = create_document(&IID_IXMLDOMDocument);
12628 doc2 = create_document(&IID_IXMLDOMDocument);
12629 doc3 = create_document(&IID_IXMLDOMDocument);
12630
12631 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &b);
12632 ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr);
12633 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformSSXML), &b);
12634 ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr);
12635
12636 V_VT(&v) = VT_UNKNOWN;
12637 V_UNKNOWN(&v) = &transformdest;
12638 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
12639 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr);
12640
12641 V_VT(&v) = VT_UNKNOWN;
12642 V_UNKNOWN(&v) = NULL;
12643 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
12644 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr);
12645
12646 V_VT(&v) = VT_DISPATCH;
12647 V_DISPATCH(&v) = NULL;
12648 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
12649 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr);
12650
12651 V_VT(&v) = VT_DISPATCH;
12652 V_DISPATCH(&v) = (IDispatch *)doc3;
12653 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
12654 ok(hr == S_OK, "Failed to transform node, hr %#x.\n", hr);
12655
12656 IXMLDOMDocument_Release(doc3);
12657 IXMLDOMDocument_Release(doc2);
12658 IXMLDOMDocument_Release(doc);
12659 free_bstrs();
12660 }
12661
12662 START_TEST(domdoc)
12663 {
12664 HRESULT hr;
12665
12666 hr = CoInitialize( NULL );
12667 ok( hr == S_OK, "failed to init com\n");
12668 if (hr != S_OK) return;
12669
12670 get_class_support_data(domdoc_support_data);
12671 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument))
12672 {
12673 win_skip("DOMDocument2 is not supported. Skipping all tests.\n");
12674 CoUninitialize();
12675 return;
12676 }
12677
12678 test_domdoc();
12679 test_persiststream();
12680 test_domnode();
12681 test_refs();
12682 test_create();
12683 test_getElementsByTagName();
12684 test_get_text();
12685 test_get_childNodes();
12686 test_get_firstChild();
12687 test_get_lastChild();
12688 test_removeChild();
12689 test_replaceChild();
12690 test_removeNamedItem();
12691 test_IXMLDOMDocument2();
12692 test_whitespace();
12693 test_XPath();
12694 test_XSLPattern();
12695 test_cloneNode();
12696 test_xmlTypes();
12697 test_save();
12698 test_testTransforms();
12699 test_namespaces_basic();
12700 test_namespaces_change();
12701 test_FormattingXML();
12702 test_nodeTypedValue();
12703 test_TransformWithLoadingLocalFile();
12704 test_put_nodeValue();
12705 test_IObjectSafety();
12706 test_splitText();
12707 test_getQualifiedItem();
12708 test_removeQualifiedItem();
12709 test_get_ownerDocument();
12710 test_setAttributeNode();
12711 test_put_dataType();
12712 test_createNode();
12713 test_create_attribute();
12714 test_get_prefix();
12715 test_default_properties();
12716 test_selectSingleNode();
12717 test_events();
12718 test_createProcessingInstruction();
12719 test_put_nodeTypedValue();
12720 test_get_xml();
12721 test_insertBefore();
12722 test_appendChild();
12723 test_get_doctype();
12724 test_get_tagName();
12725 test_get_dataType();
12726 test_get_nodeTypeString();
12727 test_get_attributes();
12728 test_selection();
12729 test_load();
12730 test_dispex();
12731 test_parseerror();
12732 test_getAttributeNode();
12733 test_getAttribute();
12734 test_supporterrorinfo();
12735 test_nodeValue();
12736 test_get_namespaces();
12737 test_put_data();
12738 test_putref_schemas();
12739 test_namedmap_newenum();
12740 test_xmlns_attribute();
12741 test_url();
12742 test_merging_text();
12743 test_transformNodeToObject();
12744
12745 test_xsltemplate();
12746 test_xsltext();
12747
12748 if (is_clsid_supported(&CLSID_MXNamespaceManager40, &IID_IMXNamespaceManager))
12749 {
12750 test_mxnamespacemanager();
12751 test_mxnamespacemanager_override();
12752 }
12753
12754 CoUninitialize();
12755 }